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
- Grant the original principal super-user access (add to superUserRoles or your AuthorizationProvider) if it legitimately needs the operation
- Use a non-super-user endpoint appropriate for the original principal's actual permissions
- Verify the X-Original-Principal value exactly matches the authenticated role in the authorization provider
- 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
- Ensure the forwarded original principal is also a super-user for super-user operations
- Verify X-Original-Principal matches the role known to the authorization provider
- Prefer tenant/namespace-scoped admin APIs for non-super-user identities
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
- Proxy not authorized for super-user operation (proxy:%s)
- Invalid combination of Original principal cannot be empty if
- This operation requires super-user access
- Unauthorized to validateBothSuperuserAndBrokerOperation for
- Time-out while checking authorization
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/a33552c5c981230f.
Report an issue: GitHub.