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

  1. Grant the needed NamespaceOperation to the role: admin.namespaces().grantPermissionOnNamespace(ns, role, EnumSet.of(operation))
  2. Add the caller to broker's superUserRoles if it is an infrastructure identity
  3. Verify with admin.namespaces().getPermissions(ns) which roles have which actions
  4. 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

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

Related errors


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