apache/pulsar · warning · RestException
Unauthorized to validateNamespaceOperation for operation [%s
Error message
Unauthorized to validateNamespaceOperation for operation [%s] on namespace [%s]
What it means
HTTP 403 FORBIDDEN thrown by validateNamespaceOperationAsync: the authorization service explicitly denied the requested namespace-level operation (e.g. produce, consume, subscribe, unload, get-topics) for the caller. Unlike tenant failures (401), this is a definitive policy denial on the namespace.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java:1029
public void validateNamespaceOperation(NamespaceName namespaceName, NamespaceOperation operation) {
sync(()-> validateNamespaceOperationAsync(namespaceName, operation));
}
public CompletableFuture<Void> validateNamespaceOperationAsync(NamespaceName namespaceName,
NamespaceOperation operation) {
if (pulsar().getConfiguration().isAuthenticationEnabled()
&& pulsar().getBrokerService().isAuthorizationEnabled()) {
if (!isClientAuthenticated(clientAppId())) {
return FutureUtil.failedFuture(
new RestException(Status.FORBIDDEN, "Need to authenticate to perform the request"));
}
return pulsar().getBrokerService().getAuthorizationService()
.allowNamespaceOperationAsync(namespaceName, operation, originalPrincipal(),
clientAppId(), clientAuthData())
.thenAccept(isAuthorized -> {
if (!isAuthorized) {
throw new RestException(Status.FORBIDDEN,
String.format("Unauthorized to validateNamespaceOperation for"
+ " operation [%s] on namespace [%s]", operation.toString(), namespaceName));
}
});
}
return CompletableFuture.completedFuture(null);
}
public void validateNamespacePolicyOperation(NamespaceName namespaceName, PolicyName policy,
PolicyOperation operation) {
sync(()-> validateNamespacePolicyOperationAsync(namespaceName, policy, operation));
}
public CompletableFuture<Void> validateNamespacePolicyOperationAsync(NamespaceName namespaceName,
PolicyName policy,
PolicyOperation operation) {
if (pulsar().getConfiguration().isAuthenticationEnabled()
&& pulsar().getBrokerService().isAuthorizationEnabled()) {View on GitHub (pinned to 820761864e)
Solutions
- Grant the needed NamespaceOperation to the role: admin.namespaces().grantPermissionOnNamespace(ns, role, EnumSet.of(operation))
- Add the caller to broker's superUserRoles if it is an infrastructure identity
- Verify with admin.namespaces().getPermissions(ns) which roles have which actions
- Check whether the operation uses originalPrincipal via a proxy and grant that principal too
Example fix
// before: FORBIDDEN on namespace op
admin.namespaces().unload(NamespaceName.get("public/default"));
// after: grant the operation
admin.namespaces().grantPermissionOnNamespace("public/default", "ops-role",
EnumSet.of(NamespaceOperation.UNLOAD, NamespaceOperation.GET_BUNDLE)); Defensive patterns
Strategy: validation
Validate before calling
Map<String, Set<NamespaceOperation>> perms = admin.namespaces().getPermissions(ns);
if (!perms.getOrDefault(myRole, Set.of()).contains(NamespaceOperation.PRODUCE)) {
throw new IllegalStateException("missing PRODUCE on " + ns);
} Try / catch
try {
nsOp(ns);
} catch (PulsarAdminException e) {
if (e.getStatusCode() == 403 && e.getMessage().contains("validateNamespaceOperation")) {
throw new SecurityException("grant NamespaceOperation to role", e);
} else throw e;
} Prevention
- Check getPermissions before performing namespace operations
- Grant explicit operations rather than relying on superuser
- Re-audit grants after enabling authorization
When it happens
Trigger: Any admin/client operation that validates a namespace operation where allowNamespaceOperationAsync returns false — e.g. producing to a namespace without PRODUCE grant, calling unload/getPermissions without the needed operation grant.
Common situations: Namespace grants never applied to the new role; permissions revoked during policy cleanup; superUserRoles misconfigured on the broker; authorizationEnabled enabled later, exposing previously unauthenticated usage.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unauthorized to validateNamespacePolicyOperation for operati
- Cluster [%s] is not in the list of allowed clusters list for
- Unauthorized to validateTenantOperation for originalPrincipa
- Invalid broker configuration. Authentication must be enabled
- Broker is forbidden to do read-write operations
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/25e1006a909237c4.
Report an issue: GitHub.