apache/pulsar · error · RestException
Cluster [%s] is not in the list of allowed clusters list for
Error message
Cluster [%s] is not in the list of allowed clusters list for tenant [%s]
What it means
Each Pulsar tenant has an allowedClusters list. validateClusterForTenant checks that the cluster the operation targets (e.g. where a namespace is being created) is in that tenant's allowedClusters and throws 403 FORBIDDEN otherwise. It is a tenant-scoped cluster allowlist check, not a generic auth failure.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java:486
protected void validateClusterForTenant(String tenant, String cluster) {
TenantInfo tenantInfo;
try {
tenantInfo = pulsar().getPulsarResources().getTenantResources().getTenant(tenant)
.orElseThrow(() -> new RestException(Status.NOT_FOUND, "Tenant does not exist"));
} catch (RestException e) {
log.warn().attr("tenant", tenant).log("Failed to get tenant admin data for tenant");
throw e;
} catch (Exception e) {
log.error().attr("tenant", tenant).exception(e).log("Failed to get tenant admin data for tenant");
throw new RestException(e);
}
// Check if tenant is allowed on the cluster
if (!tenantInfo.getAllowedClusters().contains(cluster)) {
String msg = String.format("Cluster [%s] is not in the list of allowed clusters list for tenant [%s]",
cluster, tenant);
log.info(msg);
throw new RestException(Status.FORBIDDEN, msg);
}
log.info().attr("tenant", tenant).log("Successfully validated clusters on tenant");
}
protected CompletableFuture<Void> validateClusterForTenantAsync(String tenant, String cluster) {
return pulsar().getPulsarResources().getTenantResources().getTenantAsync(tenant)
.thenAccept(tenantInfo -> {
if (tenantInfo.isEmpty()) {
throw new RestException(Status.NOT_FOUND, "Tenant does not exist");
}
if (!tenantInfo.get().getAllowedClusters().contains(cluster)) {
String msg = String.format("Cluster [%s] is not in the list of allowed clusters list"
+ " for tenant [%s]", cluster, tenant);
log.info(msg);
throw new RestException(Status.FORBIDDEN, msg);
}
});
}View on GitHub (pinned to 820761864e)
Solutions
- Add the cluster to the tenant's allowed clusters: pulsar-admin tenants update <tenant> --allowed-clusters <c1,c2,...>
- If the cluster shouldn't be used, retry the operation against a cluster already in the tenant's allowedClusters
- Check the tenant's current config: pulsar-admin tenants get <tenant> and compare allowedClusters to the cluster in the failing request
Example fix
// before pulsar-admin tenants create my-tenant --allowed-clusters cluster-a // after (allow cluster-b too) pulsar-admin tenants update my-tenant --allowed-clusters cluster-a,cluster-b
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the target cluster is in the tenant's allowedClusters before the operation
Set<String> allowed = admin.tenants().getTenant(tenant).getAllowedClusters();
if (!allowed.contains(targetCluster)) {
admin.tenants().updateTenant(tenant,
new TenantInfoImpl(tenant.getAdminRoles(), append(allowed, targetCluster)));
} Prevention
- Add every cluster you operate on to the tenant's allowedClusters at provisioning
- Re-verify allowedClusters after adding or renaming clusters
- Use the tenant's allowedClusters to generate the namespace paths in automation
When it happens
Trigger: Creating/updating a namespace or namespace-isolated policy under tenant T with cluster C where T's TenantInfo.allowedClusters does not contain C. Also hit when passing --cluster to namespace/tenant admin operations against a cluster the tenant was never provisioned on.
Common situations: Tenant created with default allowedClusters but admins operate against a new/renamed cluster; cluster renamed or added after tenant creation; multi-cluster setups where geo-replication clusters weren't added to the tenant; pointing pulsar-admin (service URL) at a different cluster than the tenant covers.
Related errors
- Clusters do not exist
- Unauthorized to validateBothTenantOperationAndSuperUser for
- Don't have permission to administrate resources on this tena
- Unauthorized to validateTenantOperation for originalPrincipa
- Unauthorized to validateNamespaceOperation for operation [%s
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/ab391cbb34ba8eee.
Report an issue: GitHub.