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.
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)
Solutions
- Increase the client's auth/login timeout above the server's expected authentication latency.
- Increase the native transport auth executor capacity or reduce authenticator cost (cache credentials/LDAP lookups).
- Check server logs for authentication latency and executor queue buildup.
- 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
- Set client auth/read timeouts above expected authenticator latency
- Monitor auth executor queue depth on the server
- Keep credential backends (LDAP etc.) fast and cached
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
- Connection failures: ECONNREFUSED, ECONNRESET, and friends — why connections get refused, reset, or dropped.
Related errors
- SASL negotiation not complete
- Credential format error: username or password is empty or co
- Password must not be null
- Authentication ID must not be null
- Unable to perform authentication: ${e.getMessage()}
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/31433b5984b5b7df.
Report an issue: GitHub.