apache/hadoop · error · SaslException
Client did not send a token
Error message
Client did not send a token
What it means
Every SASL NEGOTIATE/RESPONSE message the server processes must contain a token blob for the SASL server to evaluate. When processSaslToken() is invoked on an RpcSaslProto whose token field is unset (empty message), the server fails fast with this SaslException and the handshake aborts.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java:2457
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);
}
private void switchToSimple() {
// disable SASL and blank out any SASL server
authProtocol = AuthProtocol.NONE;
disposeSasl();
}
private RpcSaslProto buildSaslResponse(SaslState state, byte[] replyToken) {
if (LOG.isDebugEnabled()) {View on GitHub (pinned to 2add963021)
Solutions
- Verify the client's Kerberos configuration (JAAS entry, keytab, krb5.conf) produces a valid initial GSS token
- Reproduce with the standard Hadoop RPC client (RPC.getProxy) to rule out custom-client bugs before debugging the server
- Align client and server hadoop-common versions so the SASL message contract matches
- Enable debug logging (HADOOP_JAAS_DEBUG=true, sun.security.krb5.debug=true) on the client to see the token it generates
Defensive patterns
Strategy: try-catch
Try / catch
try {
proxy = RPC.waitForProxy(protocol, versionID, addr, 10000, conf);
} catch (IOException e) {
if (e.getCause() instanceof SaslException
&& e.getCause().getMessage().contains("did not send a token")) {
// client-side SASL provider produced an empty/missing token: check JAAS/krb5
LOG.error("SASL handshake produced no token; verify client security config", e);
}
throw e;
} Prevention
- Smoke-test Kerberos auth (kinit, UserGroupInformation.loginUserFromKeytab) before opening RPC connections
- Run custom clients against a MiniDFSCluster/MiniRpcServer integration test to validate the SASL message contract
- Set HADOOP_JAAS_DEBUG=true in dev environments to catch empty-token causes early
When it happens
Trigger: A SASL state message (callId -33) arrives with state NEGOTIATE or RESPONSE but without the token field set; a client SASL provider yields a zero-length initial token; a buggy custom client sends the state envelope only.
Common situations: Broken Kerberos setups (bad jaas.conf/krb5.conf) where the GSS-API context produces empty tokens; custom or scripted clients that construct RpcSaslProto manually; version-skewed clients that omit the token on the first NEGOTIATE message.
Related errors
- Client sent unsupported state ${state}
- Unrecognized SASL client callback
- Server asks us to fall back to SIMPLE auth, but this client
- Can't retrieve username from tokenIdentifier.
- ${method} authentication is not enabled. Available:${enable
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/d7efda14d3b9e22a.
Report an issue: GitHub.