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

  1. Verify the client's Kerberos configuration (JAAS entry, keytab, krb5.conf) produces a valid initial GSS token
  2. Reproduce with the standard Hadoop RPC client (RPC.getProxy) to rule out custom-client bugs before debugging the server
  3. Align client and server hadoop-common versions so the SASL message contract matches
  4. 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

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


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/d7efda14d3b9e22a. Report an issue: GitHub.