{"record":{"id":"d50368db978f49f5","repo":"apache/pulsar","slug":"s-s-doesn-t-exist-d50368","errorCode":null,"errorMessage":"%s %s doesn't exist","messagePattern":"(.+?) (.+?) doesn't exist","errorType":"http","errorClass":"RestException","httpStatus":400,"severity":"error","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java","lineNumber":291,"sourceCode":"        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 (sourceName == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Source name is not provided\");\n        }\n        if (sourceConfig == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Source config is not provided\");\n        }\n\n        throwRestExceptionIfUnauthorizedForNamespace(tenant, namespace, sourceName, \"update\", authParams);\n\n        FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();\n\n        if (!functionMetaDataManager.containsFunction(tenant, namespace, sourceName)) {\n            throw new RestException(Response.Status.BAD_REQUEST,\n                    String.format(\"%s %s doesn't exist\", ComponentTypeUtils.toString(componentType), sourceName));\n        }\n\n        FunctionMetaData existingComponent =\n                functionMetaDataManager.getFunctionMetaData(tenant, namespace, sourceName);\n\n        if (!InstanceUtils.calculateSubjectType(existingComponent.getFunctionDetails()).equals(componentType)) {\n            log.error().attr(\"tenant\", tenant).attr(\"namespace\", namespace).attr(\"componentName\", sourceName)\n\n                    .attr(\"componentType\", ComponentTypeUtils.toString(componentType)).log(\"/ / is not a\");\n            throw new RestException(Response.Status.NOT_FOUND,\n                    String.format(\"%s %s doesn't exist\", ComponentTypeUtils.toString(componentType), sourceName));\n        }\n\n        SourceConfig existingSourceConfig =\n                SourceConfigUtils.convertFromDetails(existingComponent.getFunctionDetails());\n        // The rest end points take precedence over whatever is there in functionconfig\n        sourceConfig.setTenant(tenant);","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java#L273-L309","documentation":"A 400 Bad Request thrown from SourcesImpl.updateSource when the FunctionMetaDataManager reports that no function/source record exists under the given tenant, namespace, and name. ComponentTypeUtils renders the component type ('Source'), so the message reads e.g. 'Source my-src doesn't exist'. Update semantics require an existing component; the worker refuses to create one implicitly.","triggerScenarios":"PUT /admin/v3/sources/{tenant}/{namespace}/{sourceName} for a sourceName that was never registered; a typo in tenant/namespace/name so the lookup misses; the source was deleted by another actor; querying the wrong cluster/worker whose metadata doesn't include the source.","commonSituations":"Renamed sources but scripts still use the old name; environment mismatch (dev vs prod namespace); sources wiped after a bookkeeper/ zk metadata recovery; case-sensitivity mistakes (Pulsar names are case-sensitive); calling update when create was intended.","solutions":["Confirm the source exists: GET /admin/v3/sources/{tenant}/{namespace}/{sourceName}; if 404, create it with POST instead of PUT","Fix typos and case in tenant/namespace/sourceName; list sources via GET /admin/v3/sources/{tenant}/{namespace} to see valid names","Verify you are talking to the correct cluster/worker that holds the function metadata","Handle 400 'doesn't exist' in automation by falling back to the create (POST) endpoint"],"exampleFix":"// before\n// update a source that was never created -> 400 Source my-src doesn't exist\nadmin.sources().updateSource(tenant, ns, \"my-src\", cfg);\n// after\nif (admin.sources().getSource(tenant, ns, \"my-src\") == null) {\n    admin.sources().createSource(cfg);\n} else {\n    admin.sources().updateSource(tenant, ns, \"my-src\", cfg);\n}","handlingStrategy":"validation","validationCode":"try {\n    admin.sources().getSource(tenant, ns, name); // 404 here means update will fail\n} catch (org.apache.pulsar.client.admin.PulsarAdminException.NotFoundException e) {\n    admin.sources().createSource(cfg); // create instead of update\n}","typeGuard":"boolean sourceExists(PulsarAdmin admin, String tenant, String ns, String name) {\n    try { admin.sources().getSource(tenant, ns, name); return true; }\n    catch (PulsarAdminException.NotFoundException e) { return false; }\n    catch (PulsarAdminException e) { throw new RuntimeException(e); }\n}","tryCatchPattern":"try {\n    admin.sources().updateSource(tenant, ns, name, cfg);\n} catch (org.apache.pulsar.client.admin.PulsarAdminException e) {\n    if (e.getStatusCode() == 400 && e.getMessage().endsWith(\"doesn't exist\")) {\n        admin.sources().createSource(cfg); // fallback to create\n    }\n}","preventionTips":["Check existence with a GET before every update; switch to create on 404","Verify tenant/namespace/name spelling and case against listSources output","Confirm you are connected to the cluster where the source is actually registered"],"tags":["rest-api","not-found","pulsar-functions","resource-missing"],"backgroundTag":"resource-not-found","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"}