{"record":{"id":"64e753f42bf8c4d3","repo":"apache/beam","slug":"channel-is-closed","errorCode":null,"errorMessage":"Channel is closed","messagePattern":"Channel is closed","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/hadoop-file-system/src/main/java/org/apache/beam/sdk/io/hdfs/HadoopFileSystem.java","lineNumber":371,"sourceCode":"    lineage.add(scheme, segments.build(), \"/\");\n  }\n\n  /** An adapter around {@link FSDataInputStream} that implements {@link SeekableByteChannel}. */\n  private static class HadoopSeekableByteChannel implements SeekableByteChannel {\n    private final FileStatus fileStatus;\n    private final FSDataInputStream inputStream;\n    private boolean closed;\n\n    private HadoopSeekableByteChannel(FileStatus fileStatus, FSDataInputStream inputStream) {\n      this.fileStatus = fileStatus;\n      this.inputStream = inputStream;\n      this.closed = false;\n    }\n\n    @Override\n    public int read(ByteBuffer dst) throws IOException {\n      if (closed) {\n        throw new IOException(\"Channel is closed\");\n      }\n      // O length read must be supported\n      int read = 0;\n      // We avoid using the ByteBuffer based read for Hadoop because some FSDataInputStream\n      // implementations are not ByteBufferReadable,\n      // See https://issues.apache.org/jira/browse/HADOOP-14603\n      if (dst.hasArray()) {\n        // does the same as inputStream.read(dst):\n        // stores up to dst.remaining() bytes into dst.array() starting at dst.position().\n        // But dst can have an offset with its backing array hence the + dst.arrayOffset()\n        read = inputStream.read(dst.array(), dst.position() + dst.arrayOffset(), dst.remaining());\n      } else {\n        // TODO: Add support for off heap ByteBuffers in case the underlying FSDataInputStream\n        // does not support reading from a ByteBuffer.\n        read = inputStream.read(dst);\n      }\n      if (read > 0) {\n        dst.position(dst.position() + read);","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/hadoop-file-system/src/main/java/org/apache/beam/sdk/io/hdfs/HadoopFileSystem.java#L353-L389","documentation":"HadoopFileSystem's readable ByteChannel throws this IOException on any read() after the channel has been closed. It is a state guard: reading a closed channel is a programming error in the channel lifecycle.","triggerScenarios":"Calling read(ByteBuffer) on a HadoopFileSystem readable channel after close() has been called, e.g. reading in a finally block after an early close, or reusing a channel object post-close.","commonSituations":"Double-close in try-with-resources plus manual close; concurrent readers where one thread closes while another still reads; reusing a channel variable across iterations.","solutions":["Stop using the channel after close(); scope it with try-with-resources.","Guard concurrent access — close only from the owning thread or after reads complete.","Reopen the channel via HadoopFileSystem.open() if further reads are needed."],"exampleFix":"// before\nReadableByteChannel ch = fs.open(src);\nch.close();\nch.read(buf); // throws\n// after\ntry (ReadableByteChannel ch = fs.open(src)) {\n  ch.read(buf);\n}","handlingStrategy":"try-catch","validationCode":"if (channel != null && !channel.isOpen()) {\n  channel = fileSystem.open(src); // reopen before reading\n}","typeGuard":"static boolean isReadableChannel(ReadableByteChannel ch) { return ch != null && ch.isOpen(); }","tryCatchPattern":"try (ReadableByteChannel ch = fileSystem.open(src)) {\n  while (ch.read(buf) != -1) { /* process */ }\n} catch (IOException e) {\n  if (e.getMessage().equals(\"Channel is closed\")) {\n    reopenAndResume();\n  }\n}","preventionTips":["Use try-with-resources and never read after the resource block","Avoid closing channels from other threads mid-read","Reopen via fs.open() instead of reusing closed channels"],"tags":["io","channel","hadoop","closed-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}