apache/hadoop · error · IOException

Channel should be a SelectableChannel

Error message

Channel should be a SelectableChannel

What it means

checkChannelValidity requires the channel to be a SelectableChannel because the whole timeout mechanism is built on Selector.select readiness events. Channel types that cannot be registered with a Selector (e.g. FileChannel) are rejected with IOException.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/SocketIOWithTimeout.java:96

  }
  
  /** 
   * Utility function to check if channel is ok.
   * Mainly to throw IOException instead of runtime exception
   * in case of mismatch. This mismatch can occur for many runtime
   * reasons.
   */
  static void checkChannelValidity(Object channel) throws IOException {
    if (channel == null) {
      /* Most common reason is that original socket does not have a channel.
       * So making this an IOException rather than a RuntimeException.
       */
      throw new IOException("Channel is null. Check " +
                            "how the channel or socket is created.");
    }
    
    if (!(channel instanceof SelectableChannel)) {
      throw new IOException("Channel should be a SelectableChannel");
    }    
  }
  
  /**
   * Performs actual IO operations. This is not expected to block.
   *  
   * @param buf
   * @return number of bytes (or some equivalent). 0 implies underlying
   *         channel is drained completely. We will wait if more IO is 
   *         required.
   * @throws IOException
   */
  abstract int performIO(ByteBuffer buf) throws IOException;  
  
  /**
   * Performs one IO and returns number of bytes read or written.
   * It waits up to the specified timeout. If the channel is 
   * not read before the timeout, SocketTimeoutException is thrown.

View on GitHub (pinned to 2add963021)

Solutions

  1. Pass only selectable channels: SocketChannel, ServerSocketChannel, DatagramChannel
  2. For non-selectable channels, do direct blocking IO with your own timeout/deadline handling
  3. Guard with (channel instanceof SelectableChannel) before constructing the wrapper

Example fix

// before
new SocketInputStream(fileChannel, timeout); // FileChannel is not selectable

// after
new SocketInputStream(socketChannel, timeout);
Defensive patterns

Strategy: fallback

Validate before calling

if (!(channel instanceof SelectableChannel)) {
  // use direct blocking IO with manual deadline handling
  return readBlocking(channel, deadline);
}
return new SocketInputStream((SelectableChannel) channel, timeout);

Type guard

static boolean isSelectable(java.nio.channels.Channel c) {
  return c instanceof java.nio.channels.SelectableChannel;
}

Prevention

When it happens

Trigger: Constructing a SocketIOWithTimeout subclass (SocketInputStream/SocketOutputStream) with a non-selectable channel such as FileChannel or a custom Channel implementation.

Common situations: Adapting Hadoop's socket-timeout wrapper to non-socket transports; test harnesses injecting arbitrary channels; mixing file IO code into socket wrapper paths.

Related errors


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