{"record":{"id":"6275cbc967f01ad6","repo":"apache/hadoop","slug":"provided-name-has-components-instead-of-th","errorCode":null,"errorMessage":"Provided name '{}' has {} components instead of the expected 3.","messagePattern":"Provided name '(.+?)' has (.+?) components instead of the expected 3\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/SaslDataTransferServer.java","lineNumber":286,"sourceCode":"        final char[] password = name != null ? passwordFunction.apply(name) : null;\n        customizedCallbackHandler.handleCallbacks(unknownCallbacks, name, password);\n      }\n    }\n  }\n\n  /**\n   * Given a secret manager and a username encoded for the encrypted handshake,\n   * determine the encryption key.\n   * \n   * @param userName containing the keyId, blockPoolId, and nonce.\n   * @return secret encryption key.\n   * @throws IOException\n   */\n  private byte[] getEncryptionKeyFromUserName(String userName)\n      throws IOException {\n    String[] nameComponents = userName.split(NAME_DELIMITER);\n    if (nameComponents.length != 3) {\n      throw new IOException(\"Provided name '\" + userName + \"' has \" +\n          nameComponents.length + \" components instead of the expected 3.\");\n    }\n    int keyId = Integer.parseInt(nameComponents[0]);\n    String blockPoolId = nameComponents[1];\n    byte[] nonce = Base64.decodeBase64(nameComponents[2]);\n    return blockPoolTokenSecretManager.retrieveDataEncryptionKey(keyId,\n        blockPoolId, nonce);\n  }\n\n  /**\n   * Receives SASL negotiation for general-purpose handshake.\n   *\n   * @param peer connection peer\n   * @param underlyingOut connection output stream\n   * @param underlyingIn connection input stream\n   * @return new pair of streams, wrapped after SASL negotiation\n   * @throws IOException for any error\n   */","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/SaslDataTransferServer.java#L268-L304","documentation":"In the specialized encrypted data-transfer handshake, the SASL username must encode exactly three parts - encryption keyId, blockPoolId and Base64 nonce - separated by the single-space NAME_DELIMITER (' ', DataTransferSaslUtil.java:80). SaslDataTransferServer.getEncryptionKeyFromUserName splits on that delimiter and rejects any component count other than 3 before looking up the key.","triggerScenarios":"A client composing the encrypted-handshake username incorrectly (wrong delimiter, missing nonce, extra spaces that change the split count); version skew changing the encoding; corrupted input making the split yield a different number of parts.","commonSituations":"Homegrown/custom clients implementing the data-encryption-key handshake themselves; fuzzed or corrupted streams; peers running divergent Hadoop versions with incompatible username encodings.","solutions":["Align client and DataNode Hadoop versions so the encoding matches","If implementing the protocol manually, build the username exactly as keyId + \" \" + blockPoolId + \" \" + Base64(nonce)","Treat occurrences as a misbehaving/corrupted peer: capture the exchange (pcap) and identify the client from DN logs"],"exampleFix":"// before (custom client): wrong delimiter\nString userName = keyId + \"|\" + blockPoolId + \"|\" + b64Nonce;\n// after\nString userName = keyId + \" \" + blockPoolId + \" \" + b64Nonce;","handlingStrategy":"try-catch","validationCode":"// If you implement the client side, self-check before sending\nstatic String buildEncryptedHandshakeUserName(long keyId, String blockPoolId, byte[] nonce) {\n  String userName = keyId + \" \" + blockPoolId + \" \"\n      + org.apache.commons.codec.binary.Base64.encodeBase64String(nonce);\n  assert userName.split(\" \").length == 3 : \"malformed SASL username\";\n  return userName;\n}","typeGuard":null,"tryCatchPattern":"Server side: catch (IOException e) inside getEncryptionKeyFromUserName / SASL negotiation; on the 'components instead of the expected 3' message, drop and log the peer - the handshake cannot recover. Client side: verify your encoding before connecting.","preventionTips":["Do not hand-roll the encrypted handshake username; reuse DataTransferSaslUtil / SaslDataTransferClient encodings","Keep client and DN versions aligned so the username format cannot diverge"],"tags":["hdfs","sasl","encryption","datatransfer","handshake","auth-token"],"backgroundTag":"malformed-auth-token","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}