{"record":{"id":"88acd6fa6f85230c","repo":"apache/pulsar","slug":"tenant-does-not-exist-88acd6","errorCode":null,"errorMessage":"Tenant does not exist","messagePattern":"Tenant does not exist","errorType":"http","errorClass":"RestException","httpStatus":404,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java","lineNumber":337,"sourceCode":"     */\n    protected CompletableFuture<Void> validateAdminAccessForTenantAsync(String tenant) {\n        return validateAdminAccessForTenantAsync(pulsar(), clientAppId(), originalPrincipal(), tenant,\n                clientAuthData());\n    }\n\n    protected CompletableFuture<Void> validateAdminAccessForTenantAsync(\n            PulsarService pulsar, String clientAppId,\n            String originalPrincipal, String tenant,\n            AuthenticationDataSource authenticationData) {\n            log.debug()\n                    .attr(\"tenant\", tenant)\n                    .attr(\"authenticated\", (isClientAuthenticated(clientAppId)))\n                    .attr(\"role\", clientAppId)\n                    .log(\"check admin access on tenant\");\n                return pulsar.getPulsarResources().getTenantResources().getTenantAsync(tenant)\n                .thenCompose(tenantInfoOptional -> {\n                    if (tenantInfoOptional.isEmpty()) {\n                        throw new RestException(Status.NOT_FOUND, \"Tenant does not exist\");\n                    }\n                    TenantInfo tenantInfo = tenantInfoOptional.get();\n                    if (pulsar.getConfiguration().isAuthenticationEnabled() && pulsar.getConfiguration()\n                            .isAuthorizationEnabled()) {\n                        if (!isClientAuthenticated(clientAppId)) {\n                            throw new RestException(Status.FORBIDDEN, \"Need to authenticate to perform the request\");\n                        }\n                        validateOriginalPrincipal(clientAppId, originalPrincipal);\n                        if (pulsar.getConfiguration().getProxyRoles().contains(clientAppId)) {\n                            AuthorizationService authorizationService =\n                                    pulsar.getBrokerService().getAuthorizationService();\n                            return authorizationService.isTenantAdmin(tenant, clientAppId, tenantInfo,\n                                            authenticationData)\n                                .thenCompose(isTenantAdmin -> {\n                                    if (!isTenantAdmin) {\n                                            return authorizationService.isSuperUser(clientAppId, authenticationData)\n                                                .thenCombine(authorizationService.isSuperUser(originalPrincipal,\n                                                             authenticationData),","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java#L319-L355","documentation":"validateAdminAccessForTenantAsync first loads the tenant via PulsarResources' tenant resources. If the tenant does not exist in metadata storage, it throws RestException with HTTP 404 'Tenant does not exist' before any authorization checks are made.","triggerScenarios":"Calling any tenant-scoped admin REST endpoint (namespaces, topics under a tenant) with a misspelled or deleted tenant name; operating against the wrong cluster/environment whose metadata lacks the tenant; tenant deleted concurrently.","commonSituations":"Typos in tenant names in scripts/dashboards; migrating clients between clusters where the tenant wasn't created; cleanup jobs removing tenants still referenced by automation; wrong tenant part in the REST path (admin/v2/<tenant>/...).","solutions":["Verify the tenant name in the URL path is correct (GET /admin/v2/tenants to list existing tenants)","Create the tenant first: PUT /admin/v2/tenants/<tenant> with adminRoles/allowedClusters","Point the client at the correct cluster/instance where the tenant exists","Check ZK/metadata store for the tenant if you suspect replication or metadata issues"],"exampleFix":"// before\ncurl http://broker:8080/admin/v2/namespaces/mytennt/clusters\n// after\n# list tenants, then use/create the right one\ncurl http://broker:8080/admin/v2/tenants\ncurl -X PUT -H \"Content-Type: application/json\" -d '{\"adminRoles\":[\"admin\"],\"allowedClusters\":[\"standalone\"]}' http://broker:8080/admin/v2/tenants/mytenant","handlingStrategy":"try-catch","validationCode":"// caller-side pre-check\nboolean exists = admin.tenants().getList().contains(tenant);\nif (!exists) { throw new IllegalStateException(\"Tenant not found: \" + tenant); }","typeGuard":null,"tryCatchPattern":"try {\n    admin.namespaces().getNamespaces(tenant);\n} catch (PulsarAdminException e) {\n    if (e.getStatusCode() == 404) {\n        // create the tenant or fix the tenant name\n    }\n    throw e;\n}","preventionTips":["Verify tenant names with GET /admin/v2/tenants before calling tenant-scoped APIs","Centralize tenant name constants instead of inlining strings in scripts","Automate tenant creation as part of environment provisioning"],"tags":["rest-api","tenant","not-found","pulsar"],"backgroundTag":"resource-not-found","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}