apache/hadoop · warning · IOException

You cannot pass file descriptors over anything but a UNIX do

Error message

You cannot pass file descriptors over anything but a UNIX domain socket.

What it means

IOException from DataXceiver when a client sends Op.REQUEST_SHORT_CIRCUIT_FDS (asking the DataNode to pass block file descriptors over the socket) but the connection's peer has no associated DomainSocket. Passing file descriptors for short-circuit reads is only possible over a UNIX domain socket; over plain TCP the kernel cannot transfer descriptors, so the request is rejected. It almost always indicates that the client's short-circuit-read configuration expects a domain socket that is not actually in use for this connection.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataXceiver.java:377

  @Override
  public void requestShortCircuitFds(final ExtendedBlock blk,
      final Token<BlockTokenIdentifier> token,
      SlotId slotId, int maxVersion, boolean supportsReceiptVerification)
        throws IOException {
    updateCurrentThreadName("Passing file descriptors for block " + blk);
    DataOutputStream out = getBufferedOutputStream();
    checkAccess(out, true, blk, token,
        Op.REQUEST_SHORT_CIRCUIT_FDS, BlockTokenIdentifier.AccessMode.READ,
        null, null);
    BlockOpResponseProto.Builder bld = BlockOpResponseProto.newBuilder();
    FileInputStream fis[] = null;
    SlotId registeredSlotId = null;
    boolean success = false;
    try {
      try {
        if (peer.getDomainSocket() == null) {
          throw new IOException("You cannot pass file descriptors over " +
              "anything but a UNIX domain socket.");
        }
        if (slotId != null) {
          boolean isCached = datanode.data.
              isCached(blk.getBlockPoolId(), blk.getBlockId());
          datanode.shortCircuitRegistry.registerSlot(
              ExtendedBlockId.fromExtendedBlock(blk), slotId, isCached);
          registeredSlotId = slotId;
        }
        fis = datanode.requestShortCircuitFdsForRead(blk, token, maxVersion);
        Preconditions.checkState(fis != null);
        bld.setStatus(SUCCESS);
        bld.setShortCircuitAccessVersion(DataNode.CURRENT_BLOCK_FORMAT_VERSION);
      } catch (ShortCircuitFdsVersionException e) {
        bld.setStatus(ERROR_UNSUPPORTED);
        bld.setShortCircuitAccessVersion(DataNode.CURRENT_BLOCK_FORMAT_VERSION);
        bld.setMessage(e.getMessage());
      } catch (ShortCircuitFdsUnsupportedException e) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Ensure dfs.domain.socket.path points to an identical absolute path on DataNode and clients, inside a directory that exists and is writable by the datanode user (e.g. mkdir -p /var/run/hdfs; chown hdfs:hadoop /var/run/hdfs)
  2. Verify the socket actually appears at that path while the DataNode runs (ls -l /var/run/hdfs/dn_socket) and that clients can connect to it
  3. If domain sockets cannot be supported (non-Linux, restricted containers), disable FD passing/short-circuit on the client: dfs.client.read.shortcircuit=false, so clients stop issuing REQUEST_SHORT_CIRCUIT_FDS over TCP
  4. Check DataNode and client logs for DomainSocket creation warnings to confirm which side failed

Example fix

<!-- before: client requests short-circuit FDS but no usable domain socket -->
<property><name>dfs.domain.socket.path</name><value>/var/run/hdfs/dn_socket</value></property>
<!-- /var/run/hdfs missing or root-owned, connection falls back to TCP -> error -->

<!-- after: prepare the socket dir and align both sides -->
<!-- on every DN and client node: -->
<!--   sudo mkdir -p /var/run/hdfs && sudo chown hdfs:hadoop /var/run/hdfs -->
<property><name>dfs.domain.socket.path</name><value>/var/run/hdfs/dn_socket</value></property>
<property><name>dfs.client.read.shortcircuit</name><value>true</value></property>
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: only attempt short-circuit reads if the domain socket is usable
Configuration conf = new Configuration();
conf.set("dfs.client.read.shortcircuit", "true");
conf.set("dfs.domain.socket.path", "/var/run/hdfs/dn_socket");
DomainSocket sock = null;
try {
  sock = DomainSocket.attach("/var/run/hdfs/dn_socket");
} catch (IOException unusable) {
  conf.setBoolean("dfs.client.read.shortcircuit", false); // fall back to TCP cleanly
} finally {
  if (sock != null) sock.close();
}

Try / catch

try {
  blockReader = new BlockReaderFactory(...).buildShortCircuit();
} catch (IOException e) {
  if (e.getMessage().contains("anything but a UNIX domain socket")) {
    // domain socket unavailable on this path - retry with shortcircuit disabled
    conf.setBoolean("dfs.client.read.shortcircuit", false);
    blockReader = buildTcpReader(conf);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Client enables short-circuit reads (dfs.client.read.shortcircuit=true) and the DataNode is configured with dfs.domain.socket.path, but the actual connection falls back to TCP (domain socket missing, unreachable, wrong path, or permissions prevent connect) while the client still issues REQUEST_SHORT_CIRCUIT_FDS. Also seen when dfs.client.domain.socket.data.port / short-circuit settings are inconsistent between client and DataNode.

Common situations: dfs.domain.socket.path set on the DataNode but the directory (/var/run/hdfs or similar) does not exist, has wrong ownership, or is on a filesystem that does not support domain sockets (e.g. some container/NFS setups); client-side path differs from server-side path in mixed-OS or containerized deployments; running on non-Linux platforms where domain sockets for FD passing are unavailable.

Related errors


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