apache/pulsar · critical · PulsarServerException
No authorization providers are present.
Error message
No authorization providers are present.
What it means
AuthorizationService's constructor throws PulsarServerException when no authorization provider class is configured (the providerClassname branch is skipped), meaning the broker cannot perform any authorization checks.
Source
Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/AuthorizationService.java:77
public class AuthorizationService {
private final PulsarResources resources;
private final AuthorizationProvider provider;
private final ServiceConfiguration conf;
public AuthorizationService(ServiceConfiguration conf, PulsarResources pulsarResources)
throws PulsarServerException {
this.conf = conf;
try {
final String providerClassname = conf.getAuthorizationProvider();
if (StringUtils.isNotBlank(providerClassname)) {
provider = (AuthorizationProvider) Class.forName(providerClassname)
.getDeclaredConstructor().newInstance();
provider.initialize(conf, pulsarResources);
this.resources = pulsarResources;
log.info().attr("providerClassname", providerClassname).log("Loaded authorization provider");
} else {
throw new PulsarServerException("No authorization providers are present.");
}
} catch (PulsarServerException e) {
throw e;
} catch (Throwable e) {
throw new PulsarServerException("Failed to load an authorization provider.", e);
}
}
public CompletableFuture<Boolean> isSuperUser(AuthenticationParameters authParams) {
if (!isValidOriginalPrincipal(authParams)) {
return CompletableFuture.completedFuture(false);
}
if (isProxyRole(authParams.getClientRole()) && !isWebsocketPrinciple(authParams.getOriginalPrincipal())) {
CompletableFuture<Boolean> isRoleAuthorizedFuture = isSuperUser(authParams.getClientRole(),
authParams.getClientAuthenticationDataSource());
// The current paradigm is to pass the client auth data when we don't have access to the original auth data.
CompletableFuture<Boolean> isOriginalAuthorizedFuture = isSuperUser(authParams.getOriginalPrincipal(),
authParams.getClientAuthenticationDataSource());View on GitHub (pinned to 820761864e)
Solutions
- Set `authorizationProvider=org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider` in broker.conf.
- If using a custom provider, give its fully-qualified class name and ensure its jar is on the broker's classpath.
- If you don't need authorization, set `authorizationEnabled=false` so this path is not exercised.
Example fix
# before (broker.conf) authorizationEnabled=true # after authorizationEnabled=true authorizationProvider=org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider
Defensive patterns
Strategy: validation
Validate before calling
// pre-start check
String provider = config.getAuthorizationProvider();
boolean enabled = config.isAuthorizationEnabled();
if (enabled && (provider == null || provider.isBlank()))
throw new IllegalStateException("authorizationEnabled requires authorizationProvider to be set"); Type guard
boolean authConfigComplete(ServiceConfiguration c) { return !c.isAuthorizationEnabled() || (c.getAuthorizationProvider() != null && !c.getAuthorizationProvider().isBlank()); } Try / catch
try { new AuthorizationService(conf, resources); } catch (PulsarServerException e) { log.error("broker cannot start: {}", e.getMessage()); throw e; } Prevention
- Set authorizationProvider explicitly whenever authorizationEnabled=true
- Keep broker.conf templates complete when upgrading
- Smoke-test broker startup in CI with production-like config
When it happens
Trigger: Starting a broker with `authorizationEnabled=true` but without setting `authorizationProvider` to a class implementing AuthorizationProvider.
Common situations: Operators enable authorization in broker.conf but rely on a default provider class that is not wired in this code path; config file missing the authorizationProvider key after an upgrade or template change.
Related errors
- Failed to load an authorization provider.
- Invalid broker configuration. Authentication must be enabled
- Broker is forbidden to do read-write operations
- The load shedding strategy: ${loadBalancerLoadSheddingStrate
- ${key} already exists in the dynamicConfigurationMap
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/511381a7b7b7628f.
Report an issue: GitHub.