apache/pulsar · error · ParameterException

No Function Classname specified

Error message

No Function Classname specified

What it means

validateFunctionConfigs requires a className for Java/Python functions: it is needed whenever a py config is set, or a jar is set that is not a built-in ('builtin://') reference — Go functions don't need a class name. If className is empty in those cases, a ParameterException 'No Function Classname specified' is thrown.

Source

Thrown at pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdFunctions.java:701

                userCodeFile = functionConfig.getPy();
            } else if (functionConfig.getGo() != null) {
                userCodeFile = functionConfig.getGo();
            }

            if (null != runtimeFlags) {
                functionConfig.setRuntimeFlags(runtimeFlags);
            }

            // check if configs are valid
            validateFunctionConfigs(functionConfig);
        }

        protected void validateFunctionConfigs(FunctionConfig functionConfig) {
            // go doesn't need className
            if (functionConfig.getPy() != null
                    || (functionConfig.getJar() != null && !functionConfig.getJar().startsWith("builtin://"))) {
                if (StringUtils.isEmpty(functionConfig.getClassName())) {
                    throw new ParameterException("No Function Classname specified");
                }
            }
            if (StringUtils.isEmpty(functionConfig.getName())) {
                org.apache.pulsar.common.functions.Utils.inferMissingFunctionName(functionConfig);
            }
            if (StringUtils.isEmpty(functionConfig.getName())) {
                throw new IllegalArgumentException("No Function name specified");
            }
            if (StringUtils.isEmpty(functionConfig.getTenant())) {
                org.apache.pulsar.common.functions.Utils.inferMissingTenant(functionConfig);
            }
            if (StringUtils.isEmpty(functionConfig.getNamespace())) {
                org.apache.pulsar.common.functions.Utils.inferMissingNamespace(functionConfig);
            }

            if (isNotBlank(functionConfig.getJar()) && isNotBlank(functionConfig.getPy())
                    && isNotBlank(functionConfig.getGo())) {
                throw new ParameterException("Either a Java jar or a Python file or a Go executable binary needs to"

View on GitHub (pinned to 820761864e)

Solutions

  1. Add --classname with the fully qualified class implementing the function, e.g. --classname org.example.MyFunction.
  2. If using a built-in function, reference the jar as builtin://<type> and pass --function-type so className is not required.
  3. For Go functions use --go instead of --jar so the className check is skipped.

Example fix

// before
pulsar-admin functions create --name ex --jar my.jar
// after
pulsar-admin functions create --name ex --jar my.jar --classname org.example.MyFunction
Defensive patterns

Strategy: validation

Validate before calling

boolean needsClassName = pyFile != null || (jarFile != null && !jarFile.startsWith("builtin://"));
if (needsClassName && StringUtils.isEmpty(className)) {
    throw new IllegalArgumentException("--classname is required with a jar/py function");
}

Try / catch

try {
    functionsCmd.run();
} catch (ParameterException e) {
    if (e.getMessage().contains("Classname")) {
        System.err.println("Add --classname <fqcn> (not needed for builtin:// jars or Go functions).");
    }
}

Prevention

When it happens

Trigger: Functions create/update with a --jar pointing to a local/non-builtin jar and no --classname, or a --py file without a class name; built-in jars (builtin://) and Go functions are exempt.

Common situations: Deploying built-in connectors but pointing at a real jar path, forgetting --classname because the jar has one entry, or deploying Go functions while still passing a jar argument that triggers the check.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/78e31201780eadd3. Report an issue: GitHub.