{"record":{"id":"ab94ac88ff73582a","repo":"apache/pulsar","slug":"namespace-does-not-exist-ab94ac","errorCode":null,"errorMessage":"Namespace does not exist","messagePattern":"Namespace does not exist","errorType":"http","errorClass":"RestException","httpStatus":404,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java","lineNumber":808,"sourceCode":"                })\n                .thenCompose(__ -> getAuthorizationService()\n                        .grantSubscriptionPermissionAsync(namespaceName, subscription, roles, null))\n                .thenAccept(unused -> {\n                    log.info()\n                            .attr(\"role\", roles)\n                            .attr(\"subscription\", subscription)\n                            .attr(\"namespace\", namespaceName)\n                            .log(\"Successfully granted permission on subscription for role: - namespaceName\");\n                })\n                .exceptionally(ex -> {\n                    Throwable realCause = FutureUtil.unwrapCompletionException(ex);\n                    //The IllegalArgumentException and the IllegalStateException were historically thrown by the\n                    // grantPermissionAsync method, so we catch them here to ensure backwards compatibility.\n                    if (realCause.getCause() instanceof IllegalArgumentException) {\n                        log.warn()\n                                .attr(\"namespace\", namespaceName)\n                                .log(\"Failed to set permissions for namespace : does not exist\");\n                        throw new RestException(Status.NOT_FOUND, \"Namespace does not exist\");\n                    } else if (realCause.getCause() instanceof IllegalStateException) {\n                        log.warn()\n                                .attr(\"namespace\", namespaceName)\n                                .log(\"Failed to set permissions for namespace : concurrent modification\");\n                        throw new RestException(Status.CONFLICT, \"Concurrent modification\");\n                    } else {\n                        log.error()\n                                .attr(\"namespace\", namespaceName)\n                                .exceptionMessage(realCause)\n                                .log(\"Failed to get permissions for namespace\");\n                        throw new RestException(realCause);\n                    }\n                });\n    }\n\n    protected CompletableFuture<Void> internalRevokePermissionsOnNamespaceAsync(String role) {\n        return validateNamespaceOperationAsync(namespaceName, NamespaceOperation.REVOKE_PERMISSION)\n                .thenAccept(__ -> checkNotNull(role, \"Role should not be null\"))","sourceCodeStart":790,"sourceCodeEnd":826,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java#L790-L826","documentation":"HTTP 404 returned by the subscription-level permission grant API (POST /namespaces/{tenant}/{namespace}/permissions/subscription/{role}) when the underlying cause chain ends in IllegalArgumentException. The IllegalArgumentException was historically thrown by grantPermissionAsync for a missing namespace, so it is mapped to 'Namespace does not exist' for backward compatibility.","triggerScenarios":"Granting subscription permissions on a namespace that does not exist, has been deleted, or whose name is invalid, with the failure arriving as a wrapped IllegalArgumentException inside the CompletionException cause chain.","commonSituations":"ACL setup scripts referencing a namespace removed earlier; wrong tenant/namespace in automation config; calling subscription-grant during namespace creation teardown race.","solutions":["Verify the namespace exists via GET /namespaces/{tenant}/{namespace} before granting.","Correct the namespace name in the admin call.","Recreate the namespace if deletion was unintended, then retry the grant.","If you own an old client relying on IllegalArgumentException, migrate to checking the HTTP 404 response instead."],"exampleFix":"// before\nadmin.namespaces().grantPermissionOnSubscription(ns, sub, role, actions); // 404\n// after\nif (admin.namespaces().getNamespaces(tenant).contains(ns)) {\n    admin.namespaces().grantPermissionOnSubscription(ns, sub, role, actions);\n}","handlingStrategy":"validation","validationCode":"boolean exists = admin.namespaces().getNamespaces(tenant)\n        .contains(tenant + \"/\" + namespace);\nif (!exists) throw new IllegalStateException(\"Namespace does not exist: \" + namespace);","typeGuard":null,"tryCatchPattern":"try {\n    admin.namespaces().grantPermissionOnSubscription(ns, sub, role, actions);\n} catch (PulsarAdminException.NotFoundException e) {\n    // namespace missing: create it or abort\n}","preventionTips":["Verify namespace existence before subscription ACL grants","Keep ACL provisioning downstream of namespace creation in your pipeline","Fix tenant/namespace spelling at config source"],"tags":["rest-api","admin","not-found","namespace","subscription"],"backgroundTag":"namespace-not-found","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}