{"record":{"id":"c2a16a3ba6f1dc48","repo":"apache/pulsar","slug":"failed-to-load-an-authorization-provider","errorCode":null,"errorMessage":"Failed to load an authorization provider.","messagePattern":"Failed to load an authorization provider\\.","errorType":"exception","errorClass":"PulsarServerException","httpStatus":null,"severity":"critical","filePath":"pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/AuthorizationService.java","lineNumber":82,"sourceCode":"\n    public AuthorizationService(ServiceConfiguration conf, PulsarResources pulsarResources)\n            throws PulsarServerException {\n        this.conf = conf;\n        try {\n            final String providerClassname = conf.getAuthorizationProvider();\n            if (StringUtils.isNotBlank(providerClassname)) {\n                provider = (AuthorizationProvider) Class.forName(providerClassname)\n                        .getDeclaredConstructor().newInstance();\n                provider.initialize(conf, pulsarResources);\n                this.resources = pulsarResources;\n                log.info().attr(\"providerClassname\", providerClassname).log(\"Loaded authorization provider\");\n            } else {\n                throw new PulsarServerException(\"No authorization providers are present.\");\n            }\n        } catch (PulsarServerException e) {\n            throw e;\n        } catch (Throwable e) {\n            throw new PulsarServerException(\"Failed to load an authorization provider.\", e);\n        }\n    }\n\n    public CompletableFuture<Boolean> isSuperUser(AuthenticationParameters authParams) {\n        if (!isValidOriginalPrincipal(authParams)) {\n            return CompletableFuture.completedFuture(false);\n        }\n        if (isProxyRole(authParams.getClientRole()) && !isWebsocketPrinciple(authParams.getOriginalPrincipal())) {\n            CompletableFuture<Boolean> isRoleAuthorizedFuture = isSuperUser(authParams.getClientRole(),\n                    authParams.getClientAuthenticationDataSource());\n            // The current paradigm is to pass the client auth data when we don't have access to the original auth data.\n            CompletableFuture<Boolean> isOriginalAuthorizedFuture = isSuperUser(authParams.getOriginalPrincipal(),\n                    authParams.getClientAuthenticationDataSource());\n            return isRoleAuthorizedFuture.thenCombine(isOriginalAuthorizedFuture,\n                    (isRoleAuthorized, isOriginalAuthorized) -> isRoleAuthorized && isOriginalAuthorized);\n        } else {\n            return isSuperUser(authParams.getClientRole(), authParams.getClientAuthenticationDataSource());\n        }","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/AuthorizationService.java#L64-L100","documentation":"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.","triggerScenarios":"`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).","commonSituations":"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.","solutions":["Read the cause attached to this PulsarServerException — it names the real failure (ClassNotFoundException, NoSuchMethodException, initialize() error).","Verify the provider class is on the broker classpath and its FQCN in broker.conf matches exactly (case-sensitive, correct package).","Ensure the provider class is public with a public no-arg constructor.","Fix whatever makes initialize() throw: supply required configuration keys and confirm provider dependencies are present without version conflicts."],"exampleFix":"// before (broker.conf)\nauthorizationProvider=com.example.MyAuthProvider // jar missing\n// after\ndeploy my-auth-provider.jar to $PULSAR_HOME/lib\nauthorizationProvider=com.example.MyAuthProvider","handlingStrategy":"try-catch","validationCode":"try { Class<?> c = Class.forName(conf.getAuthorizationProvider()); c.getDeclaredConstructor(); } catch (Throwable t) { throw new IllegalStateException(\"provider class not loadable: \" + t, t); }","typeGuard":"boolean providerLoadable(String fqn) { try { Class.forName(fqn).getDeclaredConstructor(); return true; } catch (Throwable t) { return false; } }","tryCatchPattern":"try { new AuthorizationService(conf, resources); } catch (PulsarServerException e) { log.error(\"provider load failed; cause: {}\", e.getCause(), e); throw e; }","preventionTips":["Always inspect getCause() — the real failure is wrapped","Deploy custom provider jars to the broker lib directory","Keep provider classes public with a public no-arg constructor","Test provider initialization in an integration environment before rollout"],"tags":["authorization","classpath","broker-startup","reflection","java"],"backgroundTag":"authorization-provider-load-failed","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}