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

  1. Verify existence first: admin.sinks().getSinks(tenant, namespace) and list the target name.
  2. If the sink is new, call createSink (registerSink) instead of updateSink.
  3. Check for typos and exact case in tenant/namespace/sinkName.
  4. 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

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


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/1837960468784a6b. Report an issue: GitHub.