{"record":{"id":"385a41537edd3fc8","repo":"apache/hadoop","slug":"received-x-instead-of-x-from-client","errorCode":null,"errorMessage":"Received %x instead of %x from client.","messagePattern":"Received %x instead of %x from client\\.","errorType":"exception","errorClass":"InvalidMagicNumberException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/SaslDataTransferServer.java","lineNumber":388,"sourceCode":"   *\n   * @param peer connection peer\n   * @param underlyingOut connection output stream\n   * @param underlyingIn connection input stream\n   * @param saslProps properties of SASL negotiation\n   * @param callbackHandler for responding to SASL callbacks\n   * @return new pair of streams, wrapped after SASL negotiation\n   * @throws IOException for any error\n   */\n  private IOStreamPair doSaslHandshake(Peer peer, OutputStream underlyingOut,\n      InputStream underlyingIn, Map<String, String> saslProps,\n      CallbackHandler callbackHandler) throws IOException {\n\n    DataInputStream in = new DataInputStream(underlyingIn);\n    DataOutputStream out = new DataOutputStream(underlyingOut);\n\n    int magicNumber = in.readInt();\n    if (magicNumber != SASL_TRANSFER_MAGIC_NUMBER) {\n      throw new InvalidMagicNumberException(magicNumber, \n          dnConf.getEncryptDataTransfer());\n    }\n    try {\n      // step 1\n      SaslMessageWithHandshake message = readSaslMessageWithHandshakeSecret(in);\n      byte[] secret = message.getSecret();\n      String bpid = message.getBpid();\n      Map<String, String> dynamicSaslProps = new TreeMap<>(saslProps);\n      if (secret != null || bpid != null) {\n        // sanity check, if one is null, the other must also not be null\n        assert(secret != null && bpid != null);\n        String qop = new String(secret, StandardCharsets.UTF_8);\n        saslProps.put(Sasl.QOP, qop);\n        dynamicSaslProps.put(Sasl.QOP, qop);\n      }\n      SaslParticipant sasl = SaslParticipant.createServerSaslParticipant(\n          dynamicSaslProps, callbackHandler);\n","sourceCodeStart":370,"sourceCodeEnd":406,"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#L370-L406","documentation":"SaslDataTransferServer.doSaslHandshake requires the connection to begin with SASL_TRANSFER_MAGIC_NUMBER (0xDEADBEEF, DataTransferSaslUtil.java:86). Any other first int throws InvalidMagicNumberException, formatted as 'Received %x instead of %x from client.'; the exception also records whether the DN runs dfs.encrypt.data-transfer (isHandshake4Encryption).","triggerScenarios":"A plain (non-SASL) data-transfer client connects to a DataNode that requires SASL negotiation: it sends op/version bytes instead of the magic number, so the first int never equals 0xDEADBEEF. Also garbage/probes on the xfer port.","commonSituations":"Enabling dfs.data.transfer.protection on DataNodes while some clients (older versions, misconfigured gateways, native tools) do not negotiate SASL; port scanners hitting dfs.datanode.data.port; half-applied security configs.","solutions":["Configure dfs.data.transfer.protection identically on clients and DataNodes, then restart the clients","Upgrade clients that predate SASL data-transfer support","Check DataNode logs: these connections are refused by design - identify and remove the non-SASL client dialing the xfer port"],"exampleFix":"// before: DN requires SASL, client sends plain protocol bytes -> InvalidMagicNumberException\n// after: client hdfs-site.xml matches the DataNodes\n<property><name>dfs.data.transfer.protection</name><value>authentication</value></property>","handlingStrategy":"try-catch","validationCode":"// Client-side preflight before enabling secure data transfer on a DN:\n// ensure every DataNode you will talk to also has SASL configured,\n// e.g. via dfsadmin/JMX:\n//   for dn in $(hdfs dfsadmin -report -live | awk '/Hostname:/{print $2}'); do\n//     curl -s \"$dn:9864/jmx?qry=Hadoop:service=DataNode,name=DataNodeInfo\" \\\n//       | grep -q dfs.data.transfer.protection || echo \"DN missing protection: $dn\"\n//   done","typeGuard":null,"tryCatchPattern":"// Mirror what SaslDataTransferClient does: treat the magic-number failure as a signal\ntry {\n  saslClientNegotiation(dnPeer);\n} catch (InvalidMagicNumberException e) {\n  if (e.isHandshake4Encryption()) {\n    // DN did not even start SASL: it lacks dfs.data.transfer.protection;\n    // surface config guidance instead of retrying the connection\n  } else {\n    // trust chain rejected: report the DN address and its protection settings\n  }\n}","preventionTips":["Roll dfs.data.transfer.protection to DataNodes first, clients second, with restarts in between","Catch org.apache.hadoop.hdfs.protocol.datatransfer.sasl.InvalidMagicNumberException specifically - its isHandshake4Encryption() distinguishes the two failure modes","Monitor DN xfer ports for non-HDFS connections so probes/scanners do not masquerade as client failures"],"tags":["hdfs","sasl","datatransfer","handshake","magic-number","datanode"],"backgroundTag":"invalid-magic-number","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}