{"record":{"id":"3d8cbc6c3bd37da9","repo":"apache/pulsar","slug":"authentication-state-is-not-initialized","errorCode":null,"errorMessage":"Authentication state is not initialized","messagePattern":"Authentication state is not initialized","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderList.java","lineNumber":111,"sourceCode":"\n        private final List<AuthenticationState> states;\n        private volatile AuthenticationState authState;\n        private final AuthenticationMetrics metrics;\n\n        AuthenticationListState(List<AuthenticationState> states, AuthenticationMetrics metrics) {\n            if (states == null || states.isEmpty()) {\n                throw new IllegalArgumentException(\"Authentication state requires at least one state\");\n            }\n            this.states = states;\n            this.authState = states.get(0);\n            this.metrics = metrics;\n        }\n\n        private AuthenticationState getAuthState() throws AuthenticationException {\n            if (authState != null) {\n                return authState;\n            } else {\n                throw new AuthenticationException(\"Authentication state is not initialized\");\n            }\n        }\n\n        @Override\n        public String getAuthRole() throws AuthenticationException {\n            return getAuthState().getAuthRole();\n        }\n\n        @Override\n        public CompletableFuture<AuthData> authenticateAsync(AuthData authData) {\n            // First, attempt to authenticate with the current auth state\n            CompletableFuture<AuthData> authChallengeFuture = new CompletableFuture<>();\n            authState\n                    .authenticateAsync(authData)\n                    .whenComplete((authChallenge, ex) -> {\n                        if (ex == null) {\n                            // Current authState is still correct. Just need to return the authChallenge.\n                            authChallengeFuture.complete(authChallenge);","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderList.java#L93-L129","documentation":"AuthenticationProviderList wraps one or more delegate authentication providers, and its internal AuthenticationState must be initialized (e.g. via an init/authenticate call) before it can be queried. getAuthState() throws this AuthenticationException when the authState field is still null, meaning authentication was never performed on this connection before a caller (getAuthRole, refreshAuthentication) tried to read the role or refresh state.","triggerScenarios":"Calling getAuthRole() or refreshAuthentication() on an AuthenticationDataProvider whose AuthenticationState was never created — i.e. the connection never went through the authenticate/initialize path that populates authState.","commonSituations":"Broker or proxy code path that skips the handshake (e.g. protocol misuse or a bug where authenticate() is not called before getAuthRole()); reusing an AuthenticationDataProvider across connections; state cleared on refresh but queried again.","solutions":["Ensure the full authentication flow runs (the provider's authenticate/init step) before calling getAuthRole() or refreshAuthentication()","Check that AuthenticationProviderList.initialize was called at broker startup so delegates are set up","Inspect for null authState handling in custom code that instantiates AuthenticationDataProviderList directly"],"exampleFix":"// before\nString role = authData.getAuthRole(); // may throw if state never initialized\n// after\nAuthenticationState state = provider.getAuthStateOrNull();\nif (state == null) {\n    throw new AuthenticationException(\"Authentication not performed yet\");\n}\nString role = state.getAuthRole();","handlingStrategy":"validation","validationCode":"if (authData instanceof AuthenticationDataProviderList) {\n    AuthenticationState state = /* obtain initialized state */;\n    if (state == null) {\n        throw new AuthenticationException(\"Auth state not initialized; run authenticate() first\");\n    }\n}","typeGuard":"boolean isAuthStateReady(AuthenticationProviderList p) {\n    try { p.getAuthRole(); return true; } catch (AuthenticationException e) { return false; }\n}","tryCatchPattern":"try {\n    String role = authData.getAuthRole();\n} catch (AuthenticationException e) {\n    // re-authenticate the connection before retrying\n    provider.authenticate(dataSource);\n}","preventionTips":["Always complete the authenticate/init flow before reading role or refreshing state","Never reuse AuthenticationDataProvider across connections without re-initializing","Add a startup assertion that auth providers initialized successfully"],"tags":["authentication","broker","state"],"backgroundTag":"authentication-state-uninitialized","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}