apache/pulsar · error · RestException

Original principal not authorized for super-user operation (

Error message

Original principal not authorized for super-user operation (original:%s)

What it means

For proxied requests whose proxy role passes the super-user check, validateSuperUserAccessAsync then verifies the forwarded original principal is also a super-user. If isSuperUser(originalPrincipal) is false, the request fails with HTTP 401 even though the proxy itself was authorized.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java:246

        } catch (RestException e) {
            return FutureUtil.failedFuture(e);
        }

        if (pulsar.getConfiguration().getProxyRoles().contains(appId)) {
            BrokerService brokerService = pulsar.getBrokerService();
            return brokerService.getAuthorizationService().isSuperUser(appId, clientAuthData())
                    .thenCompose(proxyAuthorizationSuccess -> {
                        if (!proxyAuthorizationSuccess){
                            throw new RestException(Status.UNAUTHORIZED,
                                    String.format("Proxy not authorized for super-user "
                                            + "operation (proxy:%s)", appId));
                        }
                        return pulsar.getBrokerService()
                                .getAuthorizationService()
                                .isSuperUser(originalPrincipal, clientAuthData());
                    }).thenAccept(originalPrincipalAuthorizationSuccess -> {
                        if (!originalPrincipalAuthorizationSuccess){
                            throw new RestException(Status.UNAUTHORIZED,
                                    String.format("Original principal not authorized for super-user operation "
                                                    + "(original:%s)", originalPrincipal));
                        }
                            log.debug()
                                    .attr("authorized", originalPrincipal)
                                    .attr("proxyAppId", appId)
                                    .log("Successfully authorized as super-user");
                                            });
        } else {
            return pulsar.getBrokerService()
                    .getAuthorizationService()
                    .isSuperUser(appId, clientAuthData())
                    .thenAccept(proxyAuthorizationSuccess -> {
                        if (!proxyAuthorizationSuccess) {
                            throw new RestException(Status.UNAUTHORIZED,
                                    "This operation requires super-user access");
                        }
                    });

View on GitHub (pinned to 820761864e)

Solutions

  1. Grant the original principal super-user access (add to superUserRoles or your AuthorizationProvider) if it legitimately needs the operation
  2. Use a non-super-user endpoint appropriate for the original principal's actual permissions
  3. Verify the X-Original-Principal value exactly matches the authenticated role in the authorization provider
  4. If the proxy shouldn't forward other identities, call the broker directly with the super-user credentials

Example fix

// before (broker.conf)
superUserRoles=[admin,proxy]  # original principal 'app-a' missing
// after
superUserRoles=[admin,proxy,app-a]
Defensive patterns

Strategy: try-catch

Try / catch

try {
    admin.clusters().getClusters();
} catch (PulsarAdminException e) {
    if (e.getStatusCode() == 401 && e.getMessage().contains("Original principal not authorized")) {
        // grant the original principal super-user or use a scoped API
    }
    throw e;
}

Prevention

When it happens

Trigger: A super-user proxy forwards a request whose X-Original-Principal is a non-super-user role (or an empty/unknown role); end-user role changed/removed from superUserRoles while the proxy remains super-user.

Common situations: Clients connecting through an authorized proxy with their own (non-super) credentials hitting super-user-only endpoints; stale role names after IAM/kerberos changes; typo in the original principal header.

Related errors


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