{"record":{"id":"4a847d5eccd312a0","repo":"apache/pulsar","slug":"proxy-not-authorized-for-super-user-operation-pro","errorCode":null,"errorMessage":"Proxy not authorized for super-user operation (proxy:%s)","messagePattern":"Proxy not authorized for super-user operation \\(proxy:(.+?)\\)","errorType":"http","errorClass":"RestException","httpStatus":401,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java","lineNumber":237,"sourceCode":"        String appId = clientAppId();\n            log.debug()\n                    .attr(\"requestUri\", uri.getRequestUri())\n                    .attr(\"authenticated\", isClientAuthenticated(appId))\n                    .attr(\"role\", appId)\n                    .log(\"Check super user access\");\n                String originalPrincipal = originalPrincipal();\n        try {\n            validateOriginalPrincipal(appId, originalPrincipal);\n        } catch (RestException e) {\n            return FutureUtil.failedFuture(e);\n        }\n\n        if (pulsar.getConfiguration().getProxyRoles().contains(appId)) {\n            BrokerService brokerService = pulsar.getBrokerService();\n            return brokerService.getAuthorizationService().isSuperUser(appId, clientAuthData())\n                    .thenCompose(proxyAuthorizationSuccess -> {\n                        if (!proxyAuthorizationSuccess){\n                            throw new RestException(Status.UNAUTHORIZED,\n                                    String.format(\"Proxy not authorized for super-user \"\n                                            + \"operation (proxy:%s)\", appId));\n                        }\n                        return pulsar.getBrokerService()\n                                .getAuthorizationService()\n                                .isSuperUser(originalPrincipal, clientAuthData());\n                    }).thenAccept(originalPrincipalAuthorizationSuccess -> {\n                        if (!originalPrincipalAuthorizationSuccess){\n                            throw new RestException(Status.UNAUTHORIZED,\n                                    String.format(\"Original principal not authorized for super-user operation \"\n                                                    + \"(original:%s)\", originalPrincipal));\n                        }\n                            log.debug()\n                                    .attr(\"authorized\", originalPrincipal)\n                                    .attr(\"proxyAppId\", appId)\n                                    .log(\"Successfully authorized as super-user\");\n                                            });\n        } else {","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java#L219-L255","documentation":"In validateSuperUserAccessAsync, when the authenticated appId is one of the configured proxyRoles, the broker first checks whether the proxy itself is a super-user. If AuthorizationService.isSuperUser(proxy) returns false, the request is rejected with HTTP 401 before the original principal is even considered.","triggerScenarios":"A request forwarded by a Pulsar proxy whose role is not granted super-user access; calling super-user-only admin endpoints through a proxy whose role was never added to superUserRoles.","commonSituations":"Adding the proxy role to proxyRoles on the broker but forgetting to grant it super-user rights; changed/rotated proxy role not updated in superUserRoles; new deployments where authorization provider data wasn't synced.","solutions":["Add the proxy role to superUserRoles in broker.conf (or grant super-user via your AuthorizationProvider)","Confirm the proxy's authenticated role matches exactly (case) the entry in proxyRoles/superUserRoles","If the proxy should not be a super-user, use the tenant-admin APIs instead of super-user endpoints"],"exampleFix":"// before (broker.conf)\nproxyRoles=[proxy]\nsuperUserRoles=[admin]\n// after\nproxyRoles=[proxy]\nsuperUserRoles=[admin,proxy]","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    admin.clusters().getClusters();\n} catch (PulsarAdminException e) {\n    if (e.getStatusCode() == 401 && e.getMessage().contains(\"Proxy not authorized\")) {\n        // grant the proxy role super-user access\n    }\n    throw e;\n}","preventionTips":["Add the proxy role to both proxyRoles and superUserRoles on the broker","Keep proxy role names consistent across broker and proxy configs","After role rotation, update superUserRoles before redeploying the proxy"],"tags":["authorization","proxy","superuser","rest-api","pulsar"],"backgroundTag":"unauthorized-principal","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"}