{"record":{"id":"d703c0a48e6ea400","repo":"apache/pulsar","slug":"function-namespace-cannot-be-null","errorCode":null,"errorMessage":"Function namespace cannot be null","messagePattern":"Function namespace cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java","lineNumber":794,"sourceCode":"        }\n    }\n\n    private static void verifyNoTopicClash(Collection<String> inputTopics, String outputTopic)\n            throws IllegalArgumentException {\n        if (inputTopics.contains(outputTopic)) {\n            throw new IllegalArgumentException(\n                    String.format(\n                            \"Output topic %s is also being used as an input topic (topics must be one or the other)\",\n                            outputTopic));\n        }\n    }\n\n    public static void doCommonChecks(FunctionConfig functionConfig) {\n        if (isEmpty(functionConfig.getTenant())) {\n            throw new IllegalArgumentException(\"Function tenant cannot be null\");\n        }\n        if (isEmpty(functionConfig.getNamespace())) {\n            throw new IllegalArgumentException(\"Function namespace cannot be null\");\n        }\n        if (isEmpty(functionConfig.getName())) {\n            throw new IllegalArgumentException(\"Function name cannot be null\");\n        }\n        // go doesn't need className. Java className is done in doJavaChecks.\n        if (functionConfig.getRuntime() == FunctionConfig.Runtime.PYTHON) {\n            if (isEmpty(functionConfig.getClassName())) {\n                throw new IllegalArgumentException(\"Function classname cannot be null\");\n            }\n        }\n\n        Collection<String> allInputTopics = collectAllInputTopics(functionConfig);\n        if (allInputTopics.isEmpty()) {\n            throw new IllegalArgumentException(\"No input topic(s) specified for the function\");\n        }\n        for (String topic : allInputTopics) {\n            if (!TopicName.isValid(topic)) {\n                throw new IllegalArgumentException(String.format(\"Input topic %s is invalid\", topic));","sourceCodeStart":776,"sourceCodeEnd":812,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java#L776-L812","documentation":"doCommonChecks requires a namespace on the function config; the namespace is the second segment of the fully-qualified function name (tenant/namespace/name). When getNamespace() is null or empty, validation throws this IllegalArgumentException before any submit reaches the functions worker.","triggerScenarios":"Submitting a function (create/update through FunctionConfigUtils.validateJavaFunction or validateNonJavaFunction, REST API, or pulsar-admin) with a FunctionConfig lacking setNamespace(); YAML/JSON config files missing the 'namespace' key.","commonSituations":"Programmatic FunctionConfig construction where only tenant and name were set; hand-written YAML templates omitting 'namespace'; migration scripts that changed the config schema and dropped the namespace field.","solutions":["Call functionConfig.setNamespace(\"default\") (or the intended namespace) before submitting.","Add the missing 'namespace' key to the YAML/JSON config file.","Ensure the namespace exists under the tenant (create it via pulsar-admin namespaces create if needed).","After deserialization, check the value is non-null and non-empty before calling create."],"exampleFix":"// before\nconfig.setTenant(\"public\");\nconfig.setName(\"my-fn\");\n// after\nconfig.setTenant(\"public\");\nconfig.setNamespace(\"default\");\nconfig.setName(\"my-fn\");","handlingStrategy":"validation","validationCode":"if (config == null || config.getNamespace() == null || config.getNamespace().trim().isEmpty()) {\n    throw new IllegalArgumentException(\"FunctionConfig.namespace must be set before submission\");\n}","typeGuard":"static boolean hasNamespace(FunctionConfig c) {\n    return c != null && c.getNamespace() != null && !c.getNamespace().trim().isEmpty();\n}","tryCatchPattern":"try {\n    FunctionConfigUtils.validateNonJavaFunction(functionConfig, null);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"namespace\")) {\n        throw new IllegalStateException(\"Provide --namespace (e.g. default) when creating the function\", e);\n    }\n    throw e;\n}","preventionTips":["Default the namespace to \"default\" in config builders when unset.","Validate tenant/namespace/name together with one helper before any submit.","Check YAML indentation so the 'namespace' key actually deserializes.","Create the namespace under the tenant (pulsar-admin namespaces create) before deploying."],"tags":["pulsar","functions","configuration","validation"],"backgroundTag":"required-field-missing","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}