{"record":{"id":"1837960468784a6b","repo":"apache/pulsar","slug":"s-s-doesn-t-exist-183796","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/SinksImpl.java","lineNumber":297,"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 (sinkName == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Sink name is not provided\");\n        }\n        if (sinkConfig == null) {\n            throw new RestException(Response.Status.BAD_REQUEST, \"Sink config is not provided\");\n        }\n\n        throwRestExceptionIfUnauthorizedForNamespace(tenant, namespace, sinkName, \"update\", authParams);\n\n        FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();\n\n        if (!functionMetaDataManager.containsFunction(tenant, namespace, sinkName)) {\n            throw new RestException(Response.Status.BAD_REQUEST,\n                    String.format(\"%s %s doesn't exist\", ComponentTypeUtils.toString(componentType), sinkName));\n        }\n\n        FunctionMetaData existingComponent =\n                functionMetaDataManager.getFunctionMetaData(tenant, namespace, sinkName);\n\n        if (!InstanceUtils.calculateSubjectType(existingComponent.getFunctionDetails()).equals(componentType)) {\n            log.error().attr(\"tenant\", tenant).attr(\"namespace\", namespace).attr(\"componentName\", sinkName)\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), sinkName));\n        }\n\n\n        SinkConfig existingSinkConfig = SinkConfigUtils.convertFromDetails(existingComponent.getFunctionDetails());\n        // The rest end points take precedence over whatever is there in functionconfig\n        sinkConfig.setTenant(tenant);","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SinksImpl.java#L279-L315","documentation":"updateSink only updates sinks that already exist. After authorization, the worker checks functionMetaDataManager.containsFunction(tenant, namespace, sinkName); if absent it returns HTTP 400 'Sink <name> doesn't exist'. Updates are not implicit creates — use registerSink/createSink for new components. (The same message is also used with status 404 when the component exists but is of a different type.)","triggerScenarios":"Calling PUT /admin/v3/sinks/{t}/{ns}/{name} where no sink with that fully-qualified name is registered; typo in name/namespace; the sink was deleted or the worker's function metadata manager hasn't synced yet after creation on another node.","commonSituations":"Renaming components in CI/CD while old update jobs still run; environment mismatch (updating against a different cluster than where the sink was created); case-sensitivity mistakes in the name; race between createSink and updateSink calls.","solutions":["Verify existence first: admin.sinks().getSinks(tenant, namespace) and list the target name.","If the sink is new, call createSink (registerSink) instead of updateSink.","Check for typos and exact case in tenant/namespace/sinkName.","If created moments ago, retry after the function metadata has propagated across the cluster (or hit the same worker that owns the metadata)."],"exampleFix":"// before: blind update\nadmin.sinks().updateSink(cfg, narPath); // sink absent -> 400\n// after: create-or-update\nif (admin.sinks().getSinks(\"t\", \"ns\").contains(\"my-sink\")) {\n    admin.sinks().updateSink(cfg, narPath);\n} else {\n    admin.sinks().createSink(cfg, narPath);\n}","handlingStrategy":"validation","validationCode":"boolean exists = admin.sinks().getSinks(tenant, namespace).contains(sinkName);\nif (!exists) throw new IllegalStateException(\"Sink \" + sinkName + \" does not exist; create it first\");","typeGuard":null,"tryCatchPattern":"try { admin.sinks().updateSink(cfg, archive); } catch (PulsarAdminException e) { if (e.getStatusCode() == 400 && e.getMessage().endsWith(\"doesn't exist\")) { admin.sinks().createSink(cfg, archive); } else throw e; }","preventionTips":["Implement create-or-update logic keyed on getSinks()/getSinkConfig()","Use exact, case-sensitive names consistently across environments","Allow brief delay after createSink before updateSink in clustered setups","Point client tooling at the correct cluster/tenant environment to avoid cross-env lookups"],"tags":["rest-api","not-found","pulsar-functions","lifecycle"],"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-14T05:17:10.506Z"}