apache/pulsar · error · RestException

Tenant does not exist

Error message

Tenant does not exist

What it means

registerSink catches PulsarAdminException.NotFoundException from the PulsarAdmin tenant lookup and rethrows it as a 400 Bad Request RestException with the message "Tenant does not exist". It is thrown when the tenant referenced by the registration request has no corresponding tenant record in the broker's metadata store.

Source

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

                if (namespaces != null && !namespaces.contains(qualifiedNamespaceWithCluster)) {
                    log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", sinkName)

                            .attr("namespace3", namespace).log("/ / Namespace does not exist");
                    throw new RestException(Response.Status.BAD_REQUEST, "Namespace does not exist");
                }
            }
        } catch (PulsarAdminException.NotAuthorizedException e) {
            log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", sinkName)

                    .attr("componentType", ComponentTypeUtils.toString(componentType))

                    .log("/ / Client is not authorized to operate on tenant");
            throw new RestException(Response.Status.UNAUTHORIZED, "Client is not authorized to perform operation");
        } catch (PulsarAdminException.NotFoundException e) {
            log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", sinkName)

                    .attr("tenant3", tenant).log("/ / Tenant does not exist");
            throw new RestException(Response.Status.BAD_REQUEST, "Tenant does not exist");
        } catch (PulsarAdminException e) {
            log.error().attr("tenant", tenant).attr("namespace", namespace).attr("componentName", sinkName)

                    .exception(e).log("/ / Issues getting tenant data");
            throw new RestException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage());
        }

        FunctionMetaDataManager functionMetaDataManager = worker().getFunctionMetaDataManager();

        if (functionMetaDataManager.containsFunction(tenant, namespace, sinkName)) {
            log.error().attr("componentType", ComponentTypeUtils.toString(componentType)).attr("tenant", tenant)

                    .attr("namespace", namespace).attr("componentName", sinkName).log("/ / already exists");
            throw new RestException(Response.Status.BAD_REQUEST,
                    String.format("%s %s already exists", ComponentTypeUtils.toString(componentType), sinkName));
        }

        FunctionDetails functionDetails;

View on GitHub (pinned to 820761864e)

Solutions

  1. Create the tenant: pulsar-admin tenants create <tenant> --admin-roles <roles>.
  2. Verify the tenant name with pulsar-admin tenants list and fix typos in your request.
  3. Confirm you are pointing at the intended cluster/broker (check the worker's serviceUrl config).
  4. If the tenant was deleted unintentionally, recreate it and reapply namespace/sink resources.

Example fix

// before: tenant never created
sinks.registerSink("my-tenant", "my-ns", "my-sink", config, ...); // 400 Tenant does not exist
// after
pulsar-admin tenants create my-tenant --admin-roles admin-role
sinks.registerSink("my-tenant", "my-ns", "my-sink", config, ...);
Defensive patterns

Strategy: validation

Validate before calling

List<String> tenants = admin.tenants().getTenants();
if (!tenants.contains(tenant)) {
    throw new IllegalStateException("Tenant " + tenant + " does not exist; create it first");
}

Try / catch

try {
    sinks.registerSink(tenant, ns, name, cfg, null, null, null, authParams);
} catch (RestException e) {
    if (e.getResponse().getStatus() == 400 && "Tenant does not exist".equals(e.getMessage())) {
        // create tenant via admin API, then retry registration
    } else { throw e; }
}

Prevention

When it happens

Trigger: registerSink with a tenant name that was never created, a misspelled tenant, or a tenant that was deleted while clients still reference it; the lookup happens via worker().getBrokerAdmin().tenants().getTenantInfo(tenant).

Common situations: Configuration drift between environments (tenant exists in staging but not production); typos in tenant names in deployment scripts; tenant purged by retention/cleanup jobs; running against the wrong broker URL.

Related errors


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