{"record":{"id":"d7efda14d3b9e22a","repo":"apache/hadoop","slug":"client-did-not-send-a-token","errorCode":null,"errorMessage":"Client did not send a token","messagePattern":"Client did not send a token","errorType":"exception","errorClass":"SaslException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java","lineNumber":2457,"sourceCode":"            saslServer = createSaslServer(authMethod);\n          }\n          saslResponse = processSaslToken(saslMessage);\n          break;\n        }\n        case RESPONSE: {\n          saslResponse = processSaslToken(saslMessage);\n          break;\n        }\n        default:\n          throw new SaslException(\"Client sent unsupported state \" + state);\n      }\n      return saslResponse;\n    }\n\n    private RpcSaslProto processSaslToken(RpcSaslProto saslMessage)\n        throws SaslException {\n      if (!saslMessage.hasToken()) {\n        throw new SaslException(\"Client did not send a token\");\n      }\n      byte[] saslToken = saslMessage.getToken().toByteArray();\n      LOG.debug(\"Have read input token of size {} for processing by saslServer.evaluateResponse()\",\n          saslToken.length);\n      saslToken = saslServer.evaluateResponse(saslToken);\n      return buildSaslResponse(\n          saslServer.isComplete() ? SaslState.SUCCESS : SaslState.CHALLENGE,\n          saslToken);\n    }\n\n    private void switchToSimple() {\n      // disable SASL and blank out any SASL server\n      authProtocol = AuthProtocol.NONE;\n      disposeSasl();\n    }\n\n    private RpcSaslProto buildSaslResponse(SaslState state, byte[] replyToken) {\n      if (LOG.isDebugEnabled()) {","sourceCodeStart":2439,"sourceCodeEnd":2475,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java#L2439-L2475","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  proxy = RPC.waitForProxy(protocol, versionID, addr, 10000, conf);\n} catch (IOException e) {\n  if (e.getCause() instanceof SaslException\n      && e.getCause().getMessage().contains(\"did not send a token\")) {\n    // client-side SASL provider produced an empty/missing token: check JAAS/krb5\n    LOG.error(\"SASL handshake produced no token; verify client security config\", e);\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["sasl","authentication","kerberos","rpc","hadoop-ipc"],"backgroundTag":"sasl-negotiation-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}