apache/pulsar · error · RestException
%s %s doesn't exist
Error message
%s %s doesn't exist
What it means
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.)
Source
Thrown at pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SinksImpl.java:297
if (tenant == null) {
throw new RestException(Response.Status.BAD_REQUEST, "Tenant is not provided");
}
if (namespace == null) {
throw new RestException(Response.Status.BAD_REQUEST, "Namespace is not provided");
}
if (sinkName == null) {
throw new RestException(Response.Status.BAD_REQUEST, "Sink name is not provided");
}
if (sinkConfig == null) {
throw new RestException(Response.Status.BAD_REQUEST, "Sink config is not provided");
}
throwRestExceptionIfUnauthorizedForNamespace(tenant, namespace, sinkName, "update", authParams);
FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();
if (!functionMetaDataManager.containsFunction(tenant, namespace, sinkName)) {
throw new RestException(Response.Status.BAD_REQUEST,
String.format("%s %s doesn't exist", ComponentTypeUtils.toString(componentType), sinkName));
}
FunctionMetaData existingComponent =
functionMetaDataManager.getFunctionMetaData(tenant, namespace, sinkName);
if (!InstanceUtils.calculateSubjectType(existingComponent.getFunctionDetails()).equals(componentType)) {
log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", sinkName)
.attr("componentType", ComponentTypeUtils.toString(componentType)).log("/ / is not a");
throw new RestException(Response.Status.NOT_FOUND,
String.format("%s %s doesn't exist", ComponentTypeUtils.toString(componentType), sinkName));
}
SinkConfig existingSinkConfig = SinkConfigUtils.convertFromDetails(existingComponent.getFunctionDetails());
// The rest end points take precedence over whatever is there in functionconfig
sinkConfig.setTenant(tenant);View on GitHub (pinned to 820761864e)
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).
Example fix
// before: blind update
admin.sinks().updateSink(cfg, narPath); // sink absent -> 400
// after: create-or-update
if (admin.sinks().getSinks("t", "ns").contains("my-sink")) {
admin.sinks().updateSink(cfg, narPath);
} else {
admin.sinks().createSink(cfg, narPath);
} Defensive patterns
Strategy: validation
Validate before calling
boolean exists = admin.sinks().getSinks(tenant, namespace).contains(sinkName);
if (!exists) throw new IllegalStateException("Sink " + sinkName + " does not exist; create it first"); Try / catch
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; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- %s %s doesn't exist
- <componentType> %s doesn't exist
- Function %s doesn't exist
- %s %s doesn't exist
- %s %s doesn't exist
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/1837960468784a6b.
Report an issue: GitHub.