apache/pulsar · error · RestException

Failed to get permissions

Error message

Failed to get permissions

What it means

If the authorization check itself fails (non-timeout Exception) inside validateProducePermission, the broker logs the role/topic details and throws RestException 500 'Failed to get permissions'. The client's authorization status is unknown, so the request is failed rather than silently allowed or denied.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/rest/TopicsBase.java:718

            boolean isAuthorized;
            try {
                isAuthorized = pulsar().getBrokerService().getAuthorizationService()
                        .allowTopicOperationAsync(topicName, TopicOperation.PRODUCE, authParams)
                        .get(config().getMetadataStoreOperationTimeoutSeconds(), SECONDS);
            } catch (TimeoutException e) {
                log.warn()
                        .attr("timeoutSec", config().getMetadataStoreOperationTimeoutSeconds())
                        .attr("topic", topicName)
                        .log("Timeout while checking authorization");
                throw new RestException(Status.INTERNAL_SERVER_ERROR, "Time-out while checking authorization");
            } catch (Exception e) {
                log.warn()
                        .attr("role", authParams.getClientRole())
                        .attr("originalPrincipal", authParams.getOriginalPrincipal())
                        .attr("topic", topicName)
                        .exceptionMessage(e)
                        .log("Producer-client with Role - failed to get permissions for topic - .");
                throw new RestException(Status.INTERNAL_SERVER_ERROR, "Failed to get permissions");
            }

            if (!isAuthorized) {
                throw new RestException(Status.UNAUTHORIZED, "Unauthorized to produce to topic " + topicName);
            }
        }
    }

}

View on GitHub (pinned to 820761864e)

Solutions

  1. Inspect broker logs for the logged role/topic and underlying exception (exceptionMessage attr)
  2. Verify the AuthorizationProvider implementation and its configured backends
  3. Check permissions data integrity for the topic/namespace in the metadata store
  4. Retry the request; if persistent, fix or roll back the authorization provider/policy data

Example fix

// no client code fix; server-side: check provider
// after: wrap custom provider logic defensively
return authorizationProvider.canAccessAsync(...)
    .exceptionally(ex -> { log.error("authz failed", ex); return false; });
Defensive patterns

Strategy: retry

Validate before calling

// no reliable client pre-check; server-side authz failure. Validate role/permissions exist:
// GET /admin/v2/namespaces/{ns}/permissions returns 200 before producing

Try / catch

try {
    produceViaRest(topic, payload);
} catch (RestException e) {
    if (e.getResponse().getStatus() == 500 && e.getMessage().contains("Failed to get permissions")) {
        // retry with backoff; escalate if persistent (provider/store issue)
        backoffAndRetry(topic, payload, 2);
    } else throw e;
}

Prevention

When it happens

Trigger: allowTopicOperationAsync completes exceptionally — e.g. authorization provider throwing while loading permissions from the metadata store, deserialization failures of policy data, or provider bugs.

Common situations: Corrupt/oversized permissions data in the store; custom AuthorizationProvider exceptions; policy data format changes after broker upgrade.

Related errors


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