apache/hadoop · error · SaslException
Client sent unsupported state ${state}
Error message
Client sent unsupported state ${state} What it means
Thrown by the Hadoop IPC server while reading a SASL message from the client. The RpcSaslProto message carries a SaslState that must be NEGOTIATE (client initiating) or RESPONSE (client answering a server challenge); any other state (e.g. SUCCESS, which only the server may send) falls into the default branch and fails the handshake. The server drives the SASL state machine, so an unexpected state is treated as a protocol violation and the connection is torn down.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java:2449
// SIMPLE is a legit option above. we will send no response
if (authMethod == AuthMethod.SIMPLE) {
switchToSimple();
saslResponse = null;
break;
}
// sasl server for tokens may already be instantiated
if (saslServer == null || authMethod != AuthMethod.TOKEN) {
saslServer = createSaslServer(authMethod);
}
saslResponse = processSaslToken(saslMessage);
break;
}
case RESPONSE: {
saslResponse = processSaslToken(saslMessage);
break;
}
default:
throw new SaslException("Client sent unsupported state " + state);
}
return saslResponse;
}
private RpcSaslProto processSaslToken(RpcSaslProto saslMessage)
throws SaslException {
if (!saslMessage.hasToken()) {
throw new SaslException("Client did not send a token");
}
byte[] saslToken = saslMessage.getToken().toByteArray();
LOG.debug("Have read input token of size {} for processing by saslServer.evaluateResponse()",
saslToken.length);
saslToken = saslServer.evaluateResponse(saslToken);
return buildSaslResponse(
saslServer.isComplete() ? SaslState.SUCCESS : SaslState.CHALLENGE,
saslToken);
}
View on GitHub (pinned to 2add963021)
Solutions
- Align the client's Hadoop version with the server's (same major/minor line) so SASL state sequencing matches
- If running a custom client, send SaslState.NEGOTIATE first and only ever reply with SaslState.RESPONSE; never send SUCCESS as a client
- Point health checks, TCP probes, and load-balancer checks at the HTTP/JMX port instead of the RPC port
- Check the server log for the printed state value and compare it against RpcSaslProto.SaslState in the client's hadoop-common jar to find the version skew
Example fix
// before (custom client): client declares success itself
RpcSaslProto.newBuilder().setState(SaslState.SUCCESS).build();
// after: only NEGOTIATE to start, RESPONSE to answer challenges
RpcSaslProto msg = RpcSaslProto.newBuilder()
.setState(firstMessage ? SaslState.NEGOTIATE : SaslState.RESPONSE)
.setToken(ByteString.copyFrom(saslToken))
.build(); Defensive patterns
Strategy: try-catch
Try / catch
try {
proxy = RPC.getProxy(protocol, versionID, addr, conf);
} catch (IOException e) {
Throwable cause = e.getCause() != null ? e.getCause() : e;
if (cause instanceof SaslException
&& cause.getMessage().contains("unsupported state")) {
// client/server SASL dialect mismatch: align versions, do not blindly retry
throw new ServiceVersionMismatchException("SASL state mismatch", cause);
}
throw e;
} Prevention
- Pin client and server to the same Hadoop release line in deployment manifests
- Never hand-craft RpcSaslProto frames; use the standard RPC client
- Keep health checks off the RPC port
When it happens
Trigger: A client sends RpcSaslProto with state=SUCCESS or an unknown/invalid enum value during NEGOTIATE/RESPONSE processing; a custom or non-Hadoop client hand-crafting SASL protobuf frames; severe client/server Hadoop version skew where the SASL state machine sequencing differs.
Common situations: Monitoring agents, load balancers, or port probes speaking garbage into the RPC port that happens to decode to a bad SaslState; homegrown RPC clients built from stale protobuf definitions; mixed-version clusters during rolling upgrades where an old client negotiates SASL against a new server.
Related errors
- Client did not send a token
- Can't retrieve username from tokenIdentifier.
- FATAL_INVALID_RPC_HEADER
- ${method} authentication is not enabled. Available:${enable
- "Unexpected data length " + dataLength + "!! from " + getHos
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/cac5199d98d1bfdd.
Report an issue: GitHub.