apache/hadoop · error · IOException

Cannot create a secured connection if DataNode listens on un

Error message

Cannot create a secured connection if DataNode listens on unprivileged port (%d) and no protection is defined in configuration property %s.

What it means

SaslDataTransferServer only trusts a data connection without SASL when the DataNode listens on a privileged (<1024) xfer port; for unprivileged ports it requires dfs.data.transfer.protection to be configured. When a secured handshake is attempted on an unprivileged port with no protection configured, it throws this IOException. The source comments note this path should be unreachable because DataNode startup validates the combination (only ignore.secure.ports.for.testing can produce it), and the message intentionally omits that testing key.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/SaslDataTransferServer.java:154

      LOG.debug(
        "SASL server doing general handshake for peer = {}, datanodeId = {}",
        peer, datanodeId);
      return getSaslStreams(peer, underlyingOut, underlyingIn);
    } else if (dnConf.getIgnoreSecurePortsForTesting()) {
      // It's a secured cluster using non-privileged ports, but no SASL.  The
      // only way this can happen is if the DataNode has
      // ignore.secure.ports.for.testing configured, so this is a rare edge case.
      LOG.debug(
        "SASL server skipping handshake in secured configuration with no SASL "
        + "protection configured for peer = {}, datanodeId = {}",
        peer, datanodeId);
      return new IOStreamPair(underlyingIn, underlyingOut);
    } else {
      // The error message here intentionally does not mention
      // ignore.secure.ports.for.testing.  That's intended for dev use only.
      // This code path is not expected to execute ever, because DataNode startup
      // checks for invalid configuration and aborts.
      throw new IOException(String.format("Cannot create a secured " +
        "connection if DataNode listens on unprivileged port (%d) and no " +
        "protection is defined in configuration property %s.",
        datanodeId.getXferPort(), DFS_DATA_TRANSFER_PROTECTION_KEY));
    }
  }

  /**
   * Receives SASL negotiation for specialized encrypted handshake.
   *
   * @param peer connection peer
   * @param underlyingOut connection output stream
   * @param underlyingIn connection input stream
   * @return new pair of streams, wrapped after SASL negotiation
   * @throws IOException for any error
   */
  private IOStreamPair getEncryptedStreams(Peer peer,
      OutputStream underlyingOut, InputStream underlyingIn) throws IOException {
    if (peer.hasSecureChannel() ||

View on GitHub (pinned to 2add963021)

Solutions

  1. Set dfs.data.transfer.protection (e.g. authentication, integrity or privacy) on all DataNodes to the same value as the clients and restart them
  2. If the cluster is not actually secured, remove dfs.data.transfer.protection / dfs.encrypt.data.transfer from the client configuration
  3. Verify the DataNode's effective config and xfer port (jmx/dfsadmin) after the change

Example fix

// before: only clients have protection configured
client hdfs-site.xml: dfs.data.transfer.protection=privacy
// after: same key set on every DataNode, then restart
<property><name>dfs.data.transfer.protection</name><value>privacy</value></property>
Defensive patterns

Strategy: validation

Validate before calling

// DataNode-side preflight (what DN startup already does - keep it that way)
import org.apache.hadoop.net.NetUtils;

String protection = conf.getTrimmed("dfs.data.transfer.protection", "");
int xferPort = conf.getSocketAddr("dfs.datanode.address", "0.0.0.0:9866").getPort();
boolean privileged = xferPort < 1024;
if (!protection.isEmpty() && !privileged) {
  // SASL will be used: fine, but clients must match this value
} else if (protection.isEmpty() && !privileged
    && conf.getBoolean("ignore.secure.ports.for.testing", false)) {
  throw new IllegalStateException(
      "DN on unprivileged port " + xferPort
      + " without dfs.data.transfer.protection - clients requiring SASL will fail");
}

Try / catch

catch (IOException e) on the DN during peer handling when the message contains 'unprivileged port'; the connection cannot be salvaged - log the peer and ensure cluster-wide dfs.data.transfer.protection consistency.

Prevention

When it happens

Trigger: A client negotiates SASL with a DataNode whose xfer port is >= 1024 while dfs.data.transfer.protection is unset on the DataNode - typically because clients have dfs.data.transfer.protection (or secure data transfer expectations) but the DataNode config was never updated.

Common situations: Partial security rollout: dfs.data.transfer.protection=privacy set on clients/gateway but missing on DNs; editing the client hdfs-site.xml only; testing flags leaking into production configs.

Related errors


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