{"record":{"id":"4c9d60cc99be5d13","repo":"apache/pulsar","slug":"function-config-is-not-provided-4c9d60","errorCode":null,"errorMessage":"Function config is not provided","messagePattern":"Function config is not provided","errorType":"validation","errorClass":"RestException","httpStatus":400,"severity":"error","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/FunctionsImpl.java","lineNumber":101,"sourceCode":"                                 final String functionPkgUrl,\n                                 final FunctionConfig functionConfig,\n                                 final AuthenticationParameters authParams) {\n\n        if (!isWorkerServiceAvailable()) {\n            throwUnavailableException();\n        }\n\n        if (tenant == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Tenant is not provided\");\n        }\n        if (namespace == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Namespace is not provided\");\n        }\n        if (functionName == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Function name is not provided\");\n        }\n        if (functionConfig == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Function config is not provided\");\n        }\n\n        throwRestExceptionIfUnauthorizedForNamespace(tenant, namespace, functionName, \"register\", authParams);\n\n        try {\n            // Check tenant exists\n            worker().getBrokerAdmin().tenants().getTenantInfo(tenant);\n\n            String qualifiedNamespace = tenant + \"/\" + namespace;\n            List<String> namespaces = worker().getBrokerAdmin().namespaces().getNamespaces(tenant);\n            if (namespaces != null && !namespaces.contains(qualifiedNamespace)) {\n                String qualifiedNamespaceWithCluster = String.format(\"%s/%s/%s\", tenant,\n                        worker().getWorkerConfig().getPulsarFunctionsCluster(), namespace);\n                if (!namespaces.contains(qualifiedNamespaceWithCluster)) {\n                    log.error().attr(\"tenant\", tenant).attr(\"namespace\", namespace).attr(\"componentName\", functionName)\n\n                            .attr(\"namespace3\", namespace).log(\"/ / Namespace does not exist\");\n                    throw new RestException(Response.Status.BAD_REQUEST, \"Namespace does not exist\");","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/FunctionsImpl.java#L83-L119","documentation":"registerFunction rejects the request with HTTP 400 when the submitted FunctionConfig body is null. The config carries parallelism, resources, class name, topics, and other mandatory settings, so a null body cannot be processed.","triggerScenarios":"POST to the functions endpoint with an empty/missing JSON body, or calling the admin API with null for the FunctionConfig argument.","commonSituations":"HTTP client sending no body or wrong Content-Type so the config fails to deserialize to null; programmatic call passing null config.","solutions":["Send a complete FunctionConfig JSON body with Content-Type application/json","Verify the client library call passes a non-null FunctionConfig","Validate the config locally (tenant/namespace/name/className/parallelism) before submit"],"exampleFix":"// before\nadmin.functions().createFunction(tenant, ns, name, pkgUrl, null, null);\n// after\nFunctionConfig cfg = new FunctionConfig(); /* populate */\nadmin.functions().createFunction(tenant, ns, name, pkgUrl, cfg, null);","handlingStrategy":"validation","validationCode":"java.util.Objects.requireNonNull(cfg, \"FunctionConfig must not be null\");","typeGuard":"boolean hasConfig(FunctionConfig cfg) { return cfg != null; }","tryCatchPattern":"try { admin.functions().createFunction(...); }\ncatch (PulsarAdminException e) {\n    if (e.getStatusCode() == 400 && String.valueOf(e.getMessage()).contains(\"Function config is not provided\")) {\n        // rebuild and send a populated FunctionConfig body\n    }\n}","preventionTips":["Ensure Content-Type: application/json and a non-empty body on REST calls","Construct the config in code, never pass null literals","Dry-run serialize the config to JSON to catch null bodies"],"tags":["pulsar-functions","rest-api","validation"],"backgroundTag":"missing-required-parameter","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}