apache/pulsar · error · RestException

%s %s doesn't exist

Error message

%s %s doesn't exist

What it means

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.

Source

Thrown at pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java:291

        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 (sourceName == null) {
            throw new RestException(Response.Status.BAD_REQUEST, "Source name is not provided");
        }
        if (sourceConfig == null) {
            throw new RestException(Response.Status.BAD_REQUEST, "Source config is not provided");
        }

        throwRestExceptionIfUnauthorizedForNamespace(tenant, namespace, sourceName, "update", authParams);

        FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();

        if (!functionMetaDataManager.containsFunction(tenant, namespace, sourceName)) {
            throw new RestException(Response.Status.BAD_REQUEST,
                    String.format("%s %s doesn't exist", ComponentTypeUtils.toString(componentType), sourceName));
        }

        FunctionMetaData existingComponent =
                functionMetaDataManager.getFunctionMetaData(tenant, namespace, sourceName);

        if (!InstanceUtils.calculateSubjectType(existingComponent.getFunctionDetails()).equals(componentType)) {
            log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", sourceName)

                    .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), sourceName));
        }

        SourceConfig existingSourceConfig =
                SourceConfigUtils.convertFromDetails(existingComponent.getFunctionDetails());
        // The rest end points take precedence over whatever is there in functionconfig
        sourceConfig.setTenant(tenant);

View on GitHub (pinned to 820761864e)

Solutions

  1. Confirm the source exists: GET /admin/v3/sources/{tenant}/{namespace}/{sourceName}; if 404, create it with POST instead of PUT
  2. Fix typos and case in tenant/namespace/sourceName; list sources via GET /admin/v3/sources/{tenant}/{namespace} to see valid names
  3. Verify you are talking to the correct cluster/worker that holds the function metadata
  4. Handle 400 'doesn't exist' in automation by falling back to the create (POST) endpoint

Example fix

// before
// update a source that was never created -> 400 Source my-src doesn't exist
admin.sources().updateSource(tenant, ns, "my-src", cfg);
// after
if (admin.sources().getSource(tenant, ns, "my-src") == null) {
    admin.sources().createSource(cfg);
} else {
    admin.sources().updateSource(tenant, ns, "my-src", cfg);
}
Defensive patterns

Strategy: validation

Validate before calling

try {
    admin.sources().getSource(tenant, ns, name); // 404 here means update will fail
} catch (org.apache.pulsar.client.admin.PulsarAdminException.NotFoundException e) {
    admin.sources().createSource(cfg); // create instead of update
}

Type guard

boolean sourceExists(PulsarAdmin admin, String tenant, String ns, String name) {
    try { admin.sources().getSource(tenant, ns, name); return true; }
    catch (PulsarAdminException.NotFoundException e) { return false; }
    catch (PulsarAdminException e) { throw new RuntimeException(e); }
}

Try / catch

try {
    admin.sources().updateSource(tenant, ns, name, cfg);
} catch (org.apache.pulsar.client.admin.PulsarAdminException e) {
    if (e.getStatusCode() == 400 && e.getMessage().endsWith("doesn't exist")) {
        admin.sources().createSource(cfg); // fallback to create
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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/d50368db978f49f5. Report an issue: GitHub.