apache/cassandra · warning · AuthenticationException

Auth check after connection closed

Error message

Auth check after connection closed

What it means

AuthUtil.handleLogin queues the SASL token check on an executor; if the client disconnects while the request was waiting in that queue, the handler detects channel.isActive() == false and throws AuthenticationException("Auth check after connection closed") instead of running the (now pointless) authentication. The comment notes the client default timeout (12s) can trigger this.

Solutions

  1. Increase the client's auth/login timeout above the server's expected authentication latency.
  2. Increase the native transport auth executor capacity or reduce authenticator cost (cache credentials/LDAP lookups).
  3. Check server logs for authentication latency and executor queue buildup.
  4. On the client, retry authentication after reconnecting.

Example fix

// before (client)
cluster = Cluster.builder().addContactPoint(host).withCredentials(u, p).build();
// after
cluster = Cluster.builder().addContactPoint(host).withCredentials(u, p)
    .withSocketOptions(new SocketOptions().setConnectTimeoutMillis(30000).setReadTimeoutMillis(30000)).build();
Defensive patterns

Strategy: retry

Validate before calling

// client-side: ensure generous timeouts before login
if (socket.getSoTimeout() < 30000) socket.setSoTimeout(30000);

Try / catch

try { login(user, pass); } catch (AuthenticationException e) { if (e.getMessage().contains("connection closed")) { reconnect(); retryLogin(user, pass); } else throw e; }

Prevention

When it happens

Trigger: Client-side authentication timeout (default ~12s) expires or the client closes the socket while the login task is still queued on the auth executor; the queued task then sees an inactive channel.

Common situations: Slow authentication (expensive authenticator, overloaded auth executor, slow credential backend like LDAP) causing clients to time out and disconnect; bursty login traffic exhausting the small auth thread pool.

Understand the failure class

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/31433b5984b5b7df. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/transport/messages/AuthUtil.java:68

     * @param queryState                      The current query state
     * @param token                           The token provided in an {@link AuthResponse} from the client (or empty
     *                                        if not handling an AuthResponse).
     * @param messageToSendBasedOnNegotiation Determines what response to return on based on whether sasl negotiation
     *                                        is complete (1st parameter) and the challenege token returned from the
     *                                        negotiator (2nd parameter).
     * @return the response to send back to the client.
     */
    static Response handleLogin(Connection connection, QueryState queryState, byte[] token,
                                BiFunction<Boolean, byte[], Response> messageToSendBasedOnNegotiation)
    {
        IAuthenticator.SaslNegotiator negotiator = ((ServerConnection) connection).getSaslNegotiator(queryState);
        try
        {
            // client-side timeout can disconnect while sitting in auth executor queue so (client default 12s)
            // discard if connection closed anyway
            if (!connection.channel().isActive())
            {
                throw new AuthenticationException("Auth check after connection closed");
            }
            byte[] challenge = negotiator.evaluateResponse(token);
            if (negotiator.isComplete())
            {
                AuthenticatedUser user = negotiator.getAuthenticatedUser();
                queryState.getClientState().login(user);
                ClientMetrics.instance.markAuthSuccess(user.getAuthenticationMode());
                AuthEvents.instance.notifyAuthSuccess(queryState);
                // authentication is complete, complete the authentication flow.
                return messageToSendBasedOnNegotiation.apply(true, challenge);
            }
            else
            {
                // authentication is incomplete, continue the authentication flow.
                return messageToSendBasedOnNegotiation.apply(false, challenge);
            }
        }
        catch (AuthenticationException e)

View on GitHub (pinned to 88fd0f6a0e)