apache/pulsar · critical · PulsarServerException

Failed to load an authorization provider.

Error message

Failed to load an authorization provider.

What it means

AuthorizationService's constructor catches any Throwable while instantiating or initializing the configured authorization provider (Class.forName, newInstance, or initialize failures) and rethrows it as PulsarServerException with this message, preserving the cause.

Source

Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/AuthorizationService.java:82

    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());
            return isRoleAuthorizedFuture.thenCombine(isOriginalAuthorizedFuture,
                    (isRoleAuthorized, isOriginalAuthorized) -> isRoleAuthorized && isOriginalAuthorized);
        } else {
            return isSuperUser(authParams.getClientRole(), authParams.getClientAuthenticationDataSource());
        }

View on GitHub (pinned to 820761864e)

Solutions

  1. Read the cause attached to this PulsarServerException — it names the real failure (ClassNotFoundException, NoSuchMethodException, initialize() error).
  2. Verify the provider class is on the broker classpath and its FQCN in broker.conf matches exactly (case-sensitive, correct package).
  3. Ensure the provider class is public with a public no-arg constructor.
  4. Fix whatever makes initialize() throw: supply required configuration keys and confirm provider dependencies are present without version conflicts.

Example fix

// before (broker.conf)
authorizationProvider=com.example.MyAuthProvider // jar missing
// after
deploy my-auth-provider.jar to $PULSAR_HOME/lib
authorizationProvider=com.example.MyAuthProvider
Defensive patterns

Strategy: try-catch

Validate before calling

try { Class<?> c = Class.forName(conf.getAuthorizationProvider()); c.getDeclaredConstructor(); } catch (Throwable t) { throw new IllegalStateException("provider class not loadable: " + t, t); }

Type guard

boolean providerLoadable(String fqn) { try { Class.forName(fqn).getDeclaredConstructor(); return true; } catch (Throwable t) { return false; } }

Try / catch

try { new AuthorizationService(conf, resources); } catch (PulsarServerException e) { log.error("provider load failed; cause: {}", e.getCause(), e); throw e; }

Prevention

When it happens

Trigger: `authorizationProvider` names a class that is not on the classpath, has no no-arg constructor, fails to instantiate, or whose initialize() throws (e.g. bad provider config, missing dependencies, exception in PulsarResourceLoading).

Common situations: Custom authorization provider jar not copied into the broker's lib directory; class name typo or wrong package after a refactor; provider's initialize() throwing NPE because required config keys are absent; shaded-jar dependency conflicts hiding the class.

Related errors


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