apache/pulsar · error · RestException
Unauthorized to validateBothSuperuserAndBrokerOperation for
Error message
Unauthorized to validateBothSuperuserAndBrokerOperation for originalPrincipal [${principal}] and clientAppId [${clientAppId}] about operation [${operation}] on broker [${brokerId}] What it means
BrokersBase.validateBothSuperuserAndBrokerOperation requires the caller to pass EITHER superuser validation OR broker-operation authorization. When both fail (originalPrincipal is not a superuser and the AuthorizationService denies the broker operation), it throws HTTP 401 UNAUTHORIZED with this message listing the principal, clientAppId, operation, and brokerId.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/BrokersBase.java:571
Throwable superUserValidationException = null;
try {
superUserAccessValidation.join();
} catch (Throwable ex) {
superUserValidationException = FutureUtil.unwrapCompletionException(ex);
}
Throwable brokerOperationValidationException = null;
try {
brokerOperationValidation.join();
} catch (Throwable ex) {
brokerOperationValidationException = FutureUtil.unwrapCompletionException(ex);
}
log.debug().attr("originalPrincipal", originalPrincipal())
.attr("operation", operation.toString())
.attr("broker", brokerId)
.attr("superuserValidationError", superUserValidationException)
.attr("brokerOperationValidationError", brokerOperationValidationException)
.log("validateBothSuperuserAndBrokerOperation failed");
throw new RestException(Status.UNAUTHORIZED,
String.format("Unauthorized to validateBothSuperuserAndBrokerOperation for"
+ " originalPrincipal [%s] and clientAppId [%s] "
+ "about operation [%s] on broker [%s]",
originalPrincipal(), clientAppId(), operation.toString(), brokerId));
});
}
private CompletableFuture<Void> validateBrokerOperationAsync(String cluster, String brokerId,
BrokerOperation operation) {
final var pulsar = pulsar();
if (pulsar.getBrokerService().isAuthenticationEnabled()
&& pulsar.getBrokerService().isAuthorizationEnabled()) {
return pulsar.getBrokerService().getAuthorizationService()
.allowBrokerOperationAsync(cluster, brokerId, operation, originalPrincipal(),
clientAppId(), clientAuthData())
.thenAccept(isAuthorized -> {
if (!isAuthorized) {
throw new RestException(Status.UNAUTHORIZED,View on GitHub (pinned to 820761864e)
Solutions
- Add the principal/role to the broker's superUserRoles (broker.conf or standalone.conf) if it should have unrestricted admin access, and restart/reload.
- If superuser is not appropriate, grant the role broker-operation permission in the AuthorizationService provider (e.g. allow the role the specific BrokerOperation on the cluster) so one of the two checks passes.
- Verify the client is authenticating as the intended role (check originalPrincipal and clientAppId in the message) — often a stale or wrong auth token is being used.
- Confirm authorizationEnabled and the configured authorizationProvider on the broker match your access-control setup, and that any wildcard role rules cover this principal.
Example fix
// before: broker.conf with wrong superuser role superUserRoles=admin // after: include the role the admin client authenticates as superUserRoles=admin,ops-bot
Defensive patterns
Strategy: validation
Validate before calling
// verify role is a superuser before invoking broker admin ops
Set<String> superUsers = admin.brokers().getDynamicConfiguration("superUserRoles") == null
? Set.of() : parseRoles(admin.brokers().getDynamicConfiguration("superUserRoles"));
if (!superUsers.contains(myRole)) {
// ensure authz provider grants the BrokerOperation, or use a superuser client
} Try / catch
try {
admin.brokers().getActiveBrokers(cluster);
} catch (PulsarAdminException.NotAuthorizedException e) {
log.warn("Denied broker admin op for {} on {}", clientRole, cluster, e);
} Prevention
- Keep broker superUserRoles in sync with the roles your admin tooling authenticates as.
- Test broker admin endpoints with the exact role/token your automation uses.
- Grant broker-operation permissions in the AuthorizationProvider for non-superuser operators.
- Rotate tokens/certs carefully so the role claim (originalPrincipal) stays correct.
When it happens
Trigger: Any of getActiveBrokers, getLeaderBroker, getOwnedNamespaces, updateDynamicConfiguration, deleteDynamicConfiguration, getAllDynamicConfigurations when: (1) authorization is enabled, (2) the original principal is not in the list of superusers, and (3) the authorization provider's allowBrokerOperationAsync returns false for the requested BrokerOperation on the target cluster/broker.
Common situations: Non-superuser operators hitting /admin/v2/brokers/configuration or dynamic-config endpoints; authorization provider misconfigured (role not granted broker-level permissions in the external authz store); token/client credentials not conveying the expected role; cluster name mismatch so the provider cannot match the broker.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unauthorized to validateBrokerOperation for originalPrincipa
- Proxy not authorized for super-user operation (proxy:%s)
- Original principal not authorized for super-user operation (
- This operation requires super-user access
- Don't have permission to access this topic
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/ce670777f1069417.
Report an issue: GitHub.