apache/pulsar · error · RestException

Tenant not found

Error message

Tenant not found

What it means

A 404 NOT_FOUND thrown by the namespace listing flow when the tenant referenced in the request does not exist. After validating the tenant operation (LIST_NAMESPACES) and checking tenant existence via tenantResources().tenantExistsAsync, a missing tenant produces this error.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java:148

    protected CompletableFuture<List<String>> internalGetTenantNamespaces(String tenant) {
        if (tenant == null) {
            return FutureUtil.failedFuture(new RestException(Status.BAD_REQUEST, "Tenant should not be null"));
        }
        try {
            NamedEntity.checkName(tenant);
        } catch (IllegalArgumentException e) {
            log.warn()
                    .attr("tenant", tenant)
                    .exception(e)
                    .log("Tenant name is invalid");
            return FutureUtil.failedFuture(new RestException(Status.PRECONDITION_FAILED, "Tenant name is not valid"));
        }
        return validateTenantOperationAsync(tenant, TenantOperation.LIST_NAMESPACES)
                .thenCompose(__ -> tenantResources().tenantExistsAsync(tenant))
                .thenCompose(existed -> {
                    if (!existed) {
                        throw new RestException(Status.NOT_FOUND, "Tenant not found");
                    }
                    return tenantResources().getListOfNamespacesAsync(tenant);
                });
    }

    protected CompletableFuture<Void> internalCreateNamespace(Policies policies) {
        return validateTenantOperationAsync(namespaceName.getTenant(), TenantOperation.CREATE_NAMESPACE)
                .thenCompose(__ -> validatePoliciesReadOnlyAccessAsync())
                .thenCompose(__ -> validatePoliciesAsync(namespaceName, policies))
                .thenCompose(__ -> {
                    int maxNamespacesPerTenant = pulsar().getConfiguration().getMaxNamespacesPerTenant();
                    // no distributed locks are added here.In a concurrent scenario, the threshold will be exceeded.
                    if (maxNamespacesPerTenant > 0) {
                        return tenantResources().getListOfNamespacesAsync(namespaceName.getTenant())
                                .thenAccept(namespaces -> {
                                    if (namespaces != null && namespaces.size() > maxNamespacesPerTenant) {
                                        throw new RestException(Status.PRECONDITION_FAILED,
                                                "Exceed the maximum number of namespace in tenant :"

View on GitHub (pinned to 820761864e)

Solutions

  1. Confirm the tenant exists: GET /admin/v3/tenants (or pulsar-admin tenants list) and use an exact existing tenant name.
  2. Create the tenant if missing: pulsar-admin tenants create <tenant> with admin roles and allowed clusters.
  3. Check which cluster the request targets — the tenant may exist on a different cluster.

Example fix

// before
admin.namespaces().getNamespaces("my-tennat"); // 404
// after
if (admin.tenants().getTenants().contains("mytenant")) {
    admin.namespaces().getNamespaces("mytenant");
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!admin.tenants().getTenants().contains(tenant)) {
  throw new IllegalStateException("tenant " + tenant + " does not exist on this cluster");
}

Try / catch

try { admin.namespaces().getNamespaces(tenant); }
catch (PulsarAdminException e) {
  if (e.getStatusCode() == 404 && e.getMessage().contains("Tenant not found")) {
    admin.tenants().createTenant(tenant, ...);
  } else throw e;
}

Prevention

When it happens

Trigger: GET /admin/v3/namespaces/{tenant} where the tenant was deleted, never created, or the name is mistyped (case-sensitivity/typo) on a cluster where it doesn't exist.

Common situations: Stale configuration in clients pointing at a removed tenant; multi-cluster setups where the tenant exists only on another cluster; typos like 'my-tennat'; tenant deletion racing with namespace list calls.

Related errors


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