apache/pulsar · warning · RestException

Tenant does not exist

Error message

Tenant does not exist

What it means

validateTenantAdminAccess in MultiRolesTokenAuthorizationProvider completes with a 404 RestException when the tenant named in the authorization request has no metadata in the metadata store. Per the source comment, a client naming a nonexistent tenant is a client error and is rejected without broker-side logging.

Source

Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/MultiRolesTokenAuthorizationProvider.java:157

                                    return Optional.empty();
                                }
                                log.error().attr("tenant", tenantName).exception(cause).log("Failed to get tenant");
                                throw new RestException(cause);
                            })
                            .thenCompose(op -> {
                                if (op.isPresent()) {
                                    TenantInfo tenantInfo = op.get();
                                    if (tenantInfo.getAdminRoles() == null || tenantInfo.getAdminRoles().isEmpty()) {
                                        return CompletableFuture.completedFuture(false);
                                    }

                                    return CompletableFuture.completedFuture(roles.stream()
                                            .anyMatch(n -> tenantInfo.getAdminRoles().contains(n)));
                                }
                                // A client naming a tenant that does not exist is a client error, not a broker
                                // fault: reject it without logging. Any client can trigger this at will, and the
                                // caller (e.g. ServerCnx) already logs the rejection at its own level.
                                throw new RestException(Response.Status.NOT_FOUND, "Tenant does not exist");
                            });
                });
    }

    @SuppressWarnings({"deprecation", "unchecked"})
    private Set<String> getRoles(String role, AuthenticationDataSource authData) {
        if (authData == null || (authData instanceof AuthenticationDataSubscription
                && ((AuthenticationDataSubscription) authData).getAuthData() == null)) {
            return Collections.singleton(role);
        }

        String token = null;

        if (authData.hasDataFromCommand()) {
            // Authenticate Pulsar binary connection
            token = authData.getCommandData();
            if (StringUtils.isBlank(token)) {
                return Collections.emptySet();

View on GitHub (pinned to 820761864e)

Solutions

  1. Verify the tenant exists: `pulsar-admin tenants list` and correct the tenant name in the request.
  2. Create the missing tenant if it was never provisioned: `pulsar-admin tenants create <tenant> -r <admin-role>`.
  3. Check the broker is connected to the intended configuration/metadata store (cluster may not have this tenant).
  4. Handle HTTP 404 from the admin API in client code as 'tenant not found' rather than a permissions bug.

Example fix

// before
boolean ok = auth.checkAuthorization(tenant, ...); // tenant="mytenant" (typo, actual: my-tenant)
// after
// create or correct the tenant first
pulsarAdmin.tenants().createTenant("my-tenant", new TenantInfoImpl(adminRoles, allowedClusters));
Defensive patterns

Strategy: validation

Validate before calling

Set<String> tenants = admin.tenants().getTenants();
if (!tenants.contains(tenant)) throw new IllegalArgumentException("tenant does not exist: " + tenant);

Type guard

boolean tenantExists(PulsarAdmin admin, String tenant) { try { return admin.tenants().getTenants().contains(tenant); } catch (Exception e) { return false; } }

Try / catch

try { ...authorization check... } catch (RestException e) { if (e.getResponse().getStatus() == 404) { /* tenant not found: fix request */ } else throw e; }

Prevention

When it happens

Trigger: Calling an admin/authorization API (e.g. grantPermission or canLookup-style checks) with a tenant name that was never created, was deleted, or is misspelled in the request.

Common situations: Tenant deleted between when a script/config was written and when it ran; typo in tenant name in automation scripts or CI; case-sensitivity mismatch; multi-cluster setup where the tenant only exists on a different cluster's metadata store.

Related errors


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