{"record":{"id":"4870c9513ff3c4a3","repo":"apache/hadoop","slug":"channel-is-null-check-how-the-channel-or-socket-i","errorCode":null,"errorMessage":"Channel is null. Check how the channel or socket is created.","messagePattern":"Channel is null\\. Check how the channel or socket is created\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/SocketIOWithTimeout.java","lineNumber":91,"sourceCode":"    return !closed && channel.isOpen();\n  }\n\n  SelectableChannel getChannel() {\n    return channel;\n  }\n  \n  /** \n   * Utility function to check if channel is ok.\n   * Mainly to throw IOException instead of runtime exception\n   * in case of mismatch. This mismatch can occur for many runtime\n   * reasons.\n   */\n  static void checkChannelValidity(Object channel) throws IOException {\n    if (channel == null) {\n      /* Most common reason is that original socket does not have a channel.\n       * So making this an IOException rather than a RuntimeException.\n       */\n      throw new IOException(\"Channel is null. Check \" +\n                            \"how the channel or socket is created.\");\n    }\n    \n    if (!(channel instanceof SelectableChannel)) {\n      throw new IOException(\"Channel should be a SelectableChannel\");\n    }    \n  }\n  \n  /**\n   * Performs actual IO operations. This is not expected to block.\n   *  \n   * @param buf\n   * @return number of bytes (or some equivalent). 0 implies underlying\n   *         channel is drained completely. We will wait if more IO is \n   *         required.\n   * @throws IOException\n   */\n  abstract int performIO(ByteBuffer buf) throws IOException;  ","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/SocketIOWithTimeout.java#L73-L109","documentation":"SocketIOWithTimeout implements read/write/connect timeouts on top of java.nio select, so it requires a real channel. checkChannelValidity throws IOException when the channel is null — the dominant cause is a classic java.net.Socket (created via new Socket()) whose getChannel() returns null because it was never associated with a channel. The code deliberately uses IOException, not a RuntimeException, because this is a common setup mismatch.","triggerScenarios":"Constructing SocketInputStream/SocketOutputStream (subclasses of SocketIOWithTimeout) around a plain Socket: socket.getChannel() == null, so the wrapper cannot multiplex and throws immediately.","commonSituations":"Wrapping sockets from new Socket(host, port) or plain ServerSocket.accept() instead of SocketChannel.open()/ServerSocketChannel; custom SocketFactory implementations returning channel-less sockets; code assuming every Socket has a channel.","solutions":["Create the connection with SocketChannel.open() (or accept via ServerSocketChannel) so getChannel() is non-null","For plain sockets, use their ordinary blocking InputStream/OutputStream with SO_TIMEOUT instead of the channel-based wrappers","If you must inject sockets, check socket.getChannel() != null before building the stream wrappers"],"exampleFix":"// before\nSocket s = new Socket(host, port);\nSocketInputStream in = new SocketInputStream(s.getChannel(), timeout); // channel == null -> IOException\n\n// after\nSocketChannel ch = SocketChannel.open(new InetSocketAddress(host, port));\nSocketInputStream in = new SocketInputStream(ch, timeout);","handlingStrategy":"fallback","validationCode":"SocketChannel ch = socket.getChannel();\nif (ch == null) {\n  // fall back to blocking streams with SO_TIMEOUT\n  socket.setSoTimeout((int) timeoutMs);\n  return socket.getInputStream();\n}\nreturn new SocketInputStream(ch, timeoutMs);","typeGuard":"static boolean hasChannel(Socket s) {\n  return s != null && s.getChannel() != null;\n}","tryCatchPattern":"catch (IOException e) {\n  if (e.getMessage().contains(\"Channel is null\")) {\n    // recreate the connection via SocketChannel.open() and retry once\n  }\n}","preventionTips":["Create connections with SocketChannel.open() when channel-based wrappers will be used","Check socket.getChannel() before constructing SocketInputStream/SocketOutputStream"],"tags":["hadoop-common","network","nio","sockets","java"],"backgroundTag":"socket-missing-channel","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}