apache/cassandra · error · AuthenticationException
SASL negotiation not complete
Error message
SASL negotiation not complete
What it means
PasswordAuthenticator's SASLPlainAuthenticator tracks whether the full PLAIN SASL exchange (the client's response containing authzid/authcid/password) has been received. getAuthenticatedUser() refuses to return a user until evaluateResponse() has completed the negotiation and the authenticator state is 'complete'. Throwing AuthenticationException here prevents reading credentials before they were decoded.
Source
Thrown at src/java/org/apache/cassandra/auth/PasswordAuthenticator.java:309
private String username;
private String password;
public byte[] evaluateResponse(byte[] clientResponse) throws AuthenticationException
{
decodeCredentials(clientResponse);
complete = true;
return null;
}
public boolean isComplete()
{
return complete;
}
public AuthenticatedUser getAuthenticatedUser() throws AuthenticationException
{
if (!complete)
throw new AuthenticationException("SASL negotiation not complete");
return authenticate(username, password);
}
@Override
public AuthenticationMode getAuthenticationMode()
{
return AuthenticationMode.PASSWORD;
}
/**
* SASL PLAIN mechanism specifies that credentials are encoded in a
* sequence of UTF-8 bytes, delimited by 0 (US-ASCII NUL).
* The form is : {@code authzId<NUL>authnId<NUL>password<NUL>}
* authzId is optional, and in fact we don't care about it here as we'll
* set the authzId to match the authnId (that is, there is no concept of
* a user being authorized to act on behalf of another with this IAuthenticator).
*
* @param bytes encoded credentials string sent by the clientView on GitHub (pinned to 88fd0f6a0e)
Solutions
- Ensure the client completes the SASL PLAIN handshake: send the AuthResponse token (NUL-separated authzid/authcid/password) before the server queries the user
- In server-side/custom code, call evaluateResponse(byte[]) first and only call getAuthenticatedUser() when it signals completion
- Check driver authentication configuration (authenticator class, credentials provider) so the handshake is not aborted early
Example fix
// before
AuthenticatedUser user = negotiator.getAuthenticatedUser(); // throws if handshake incomplete
// after
byte[] response = buildPlainToken(user, pass);
if (negotiator.evaluateResponse(response) instanceof AuthenticationException)
throw new IllegalStateException("SASL handshake failed");
AuthenticatedUser user = negotiator.getAuthenticatedUser(); Defensive patterns
Strategy: try-catch
Validate before calling
if (!negotiatorComplete(negotiator)) throw new IllegalStateException("call evaluateResponse first"); Type guard
boolean saslComplete(SaslNegotiator n) { return n != null && n.getAuthenticationMode() != null && completed(n); } Try / catch
try { user = negotiator.getAuthenticatedUser(); } catch (AuthenticationException e) { handleAuthRequired(); } Prevention
- Always drive the SASL state machine in order: evaluateResponse then getAuthenticatedUser
- Wrap client auth flows in the driver's built-in auth provider instead of hand-rolling SASL
- Log negotiation state on failure to catch lifecycle misuse early
When it happens
Trigger: Calling SaslNegotiator.getAuthenticatedUser() before any call to evaluateResponse(), or after a negotiation that threw AuthenticationException (leaving complete=false). Typically from the native-protocol auth flow when the server asks for the authenticated user at the wrong lifecycle point.
Common situations: Custom client drivers skipping the SASL response step; middleware or test code instantiating PasswordAuthenticator.newSaslNegotiator() and directly querying the user; a failed/cancelled SASL handshake followed by a user lookup.
Related errors
- Credential format error: username or password is empty or co
- Password must not be null
- Authentication ID must not be null
- SASL Authentication is not supported in version 1 of the pro
- Auth check after connection closed
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/077b6f82014cbc3a.
Report an issue: GitHub.