apache/pulsar · error · AuthenticationException

Authentication state is not initialized

Error message

Authentication state is not initialized

What it means

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.

Source

Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderList.java:111

        private final List<AuthenticationState> states;
        private volatile AuthenticationState authState;
        private final AuthenticationMetrics metrics;

        AuthenticationListState(List<AuthenticationState> states, AuthenticationMetrics metrics) {
            if (states == null || states.isEmpty()) {
                throw new IllegalArgumentException("Authentication state requires at least one state");
            }
            this.states = states;
            this.authState = states.get(0);
            this.metrics = metrics;
        }

        private AuthenticationState getAuthState() throws AuthenticationException {
            if (authState != null) {
                return authState;
            } else {
                throw new AuthenticationException("Authentication state is not initialized");
            }
        }

        @Override
        public String getAuthRole() throws AuthenticationException {
            return getAuthState().getAuthRole();
        }

        @Override
        public CompletableFuture<AuthData> authenticateAsync(AuthData authData) {
            // First, attempt to authenticate with the current auth state
            CompletableFuture<AuthData> authChallengeFuture = new CompletableFuture<>();
            authState
                    .authenticateAsync(authData)
                    .whenComplete((authChallenge, ex) -> {
                        if (ex == null) {
                            // Current authState is still correct. Just need to return the authChallenge.
                            authChallengeFuture.complete(authChallenge);

View on GitHub (pinned to 820761864e)

Solutions

  1. Ensure the full authentication flow runs (the provider's authenticate/init step) before calling getAuthRole() or refreshAuthentication()
  2. Check that AuthenticationProviderList.initialize was called at broker startup so delegates are set up
  3. Inspect for null authState handling in custom code that instantiates AuthenticationDataProviderList directly

Example fix

// before
String role = authData.getAuthRole(); // may throw if state never initialized
// after
AuthenticationState state = provider.getAuthStateOrNull();
if (state == null) {
    throw new AuthenticationException("Authentication not performed yet");
}
String role = state.getAuthRole();
Defensive patterns

Strategy: validation

Validate before calling

if (authData instanceof AuthenticationDataProviderList) {
    AuthenticationState state = /* obtain initialized state */;
    if (state == null) {
        throw new AuthenticationException("Auth state not initialized; run authenticate() first");
    }
}

Type guard

boolean isAuthStateReady(AuthenticationProviderList p) {
    try { p.getAuthRole(); return true; } catch (AuthenticationException e) { return false; }
}

Try / catch

try {
    String role = authData.getAuthRole();
} catch (AuthenticationException e) {
    // re-authenticate the connection before retrying
    provider.authenticate(dataSource);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


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