apache/pulsar · error · RestException
Unauthorized to validateBothSuperuserAndClusterOperation for
Error message
Unauthorized to validateBothSuperuserAndClusterOperation for originalPrincipal [${principal}] and clientAppId [${clientAppId}] about operation [${operation}] on cluster [${cluster}] What it means
HTTP 401 (UNAUTHORIZED) thrown by validateBothSuperuserAndClusterOperation when the caller fails both authorization paths required for a cluster admin operation: the originalPrincipal is not a superuser AND fails the cluster-level operation permission check. Used by basic cluster CRUD endpoints (get/create/update/delete cluster, peer cluster management). The message includes principal, clientAppId, operation, and cluster for diagnosis.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/ClustersBase.java:1253
Throwable superUserValidationException = null;
try {
superUserAccessValidation.join();
} catch (Throwable ex) {
superUserValidationException = FutureUtil.unwrapCompletionException(ex);
}
Throwable clusterOperationValidationException = null;
try {
clusterOperationValidation.join();
} catch (Throwable ex) {
clusterOperationValidationException = FutureUtil.unwrapCompletionException(ex);
}
log.debug().attr("originalPrincipal", originalPrincipal())
.attr("operation", operation.toString())
.attr("cluster", clusterName)
.attr("superuserValidationError", superUserValidationException)
.attr("clusterOperationValidationError", clusterOperationValidationException)
.log("validateBothSuperuserAndClusterOperation failed");
throw new RestException(Status.UNAUTHORIZED,
String.format("Unauthorized to validateBothSuperuserAndClusterOperation for"
+ " originalPrincipal [%s] and clientAppId [%s] "
+ "about operation [%s] on cluster [%s]",
originalPrincipal(), clientAppId(), operation.toString(), clusterName));
});
}
private CompletableFuture<Void> validateBothSuperuserAndClusterPolicyOperation(String clusterName, PolicyName name,
PolicyOperation operation) {
final var superUserAccessValidation = validateSuperUserAccessAsync();
final var clusterOperationValidation = validateClusterPolicyOperationAsync(clusterName, name, operation);
return FutureUtil.waitForAll(List.of(superUserAccessValidation, clusterOperationValidation))
.handle((result, err) -> {
if (!superUserAccessValidation.isCompletedExceptionally()
|| !clusterOperationValidation.isCompletedExceptionally()) {
return null;
}
Throwable superUserValidationException = null;View on GitHub (pinned to 820761864e)
Solutions
- Authenticate with a role listed in superUserRoles in broker.conf, or grant the role the required cluster operation permission.
- Verify the client token/credentials are valid, unexpired, and map to the intended role (check clientAppId in the error message).
- If calling through a proxy, ensure the originalPrincipal is correctly forwarded and authorized on the broker.
- For automation, provision a dedicated admin role with the minimal required cluster permissions instead of reusing user tokens.
Example fix
// before
PulsarAdmin admin = PulsarAdmin.builder().serviceHttpUrl(url)
.authentication(AuthenticationFactory.token(userToken)).build();
admin.clusters().getCluster("c1"); // 401
// after
PulsarAdmin admin = PulsarAdmin.builder().serviceHttpUrl(url)
.authentication(AuthenticationFactory.token(adminToken)).build(); // token role in superUserRoles
admin.clusters().getCluster("c1"); Defensive patterns
Strategy: validation
Validate before calling
// client-side sanity check before calling cluster admin APIs
String role = currentTokenRole(); // however roles are derived from your token
if (!superUserRoles.contains(role) && !hasClusterPermission(role, cluster, operation)) {
throw new SecurityException("Role " + role + " lacks cluster " + operation + " on " + cluster);
} Try / catch
try {
admin.clusters().createCluster(cluster, clusterData);
} catch (PulsarAdminException.NotAuthorizedException e) {
// principal/clientAppId in message lacks superuser and cluster permission:
// switch to an authorized admin credential
} Prevention
- Use dedicated admin credentials (role in superUserRoles) for cluster administration.
- Confirm token role and expiry before running admin automation.
- When proxying, preserve originalPrincipal and ensure it is authorized on the broker.
- Grant minimal required cluster permissions to automation roles instead of sharing user tokens.
When it happens
Trigger: Any of GET/POST/PUT/DELETE /admin/v3/clusters/{cluster} (or /peers) executed with credentials whose role is neither a superuser nor granted the cluster operation (e.g. admin/produce/consume per policy); expired or wrong client token; proxy-forwarded request where originalPrincipal lost superuser rights.
Common situations: Tokens minted for a tenant-level role used for cluster administration; superuser roles edited out of broker config (superUserRoles); missing originalPrincipal authentication data when going through a proxy; version changes in authorization providers.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unauthorized to validateBothSuperuserAndClusterPolicyOperati
- Invalid broker configuration. Authentication must be enabled
- Unauthorized to validateBothSuperuserAndBrokerOperation for
- Unauthorized to validateBothTenantOperationAndSuperUser for
- Proxy not authorized for super-user operation (proxy:%s)
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/e4b7444145caf05c.
Report an issue: GitHub.