{"record":{"id":"9a19daa91ffdc141","repo":"apache/hadoop","slug":"stream-is-closed","errorCode":null,"errorMessage":"Stream is closed!","messagePattern":"Stream is closed!","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-cos/src/main/java/org/apache/hadoop/fs/cosn/CosNInputStream.java","lineNumber":275,"sourceCode":"      this.reopen(pos);\n    }\n  }\n\n  @Override\n  public long getPos() {\n    return this.position;\n  }\n\n  @Override\n  public boolean seekToNewSource(long targetPos) {\n    // Currently does not support to seek the offset of a new source\n    return false;\n  }\n\n  @Override\n  public int read() throws IOException {\n    if (this.closed) {\n      throw new IOException(FSExceptionMessages.STREAM_IS_CLOSED);\n    }\n\n    if (this.partRemaining <= 0 && this.position < this.fileSize) {\n      this.reopen(this.position);\n    }\n\n    int byteRead = -1;\n    if (this.partRemaining != 0) {\n      byteRead = this.buffer[\n          (int) (this.buffer.length - this.partRemaining)] & 0xff;\n    }\n    if (byteRead >= 0) {\n      this.position++;\n      this.partRemaining--;\n      if (null != this.statistics) {\n        this.statistics.incrementBytesRead(byteRead);\n      }\n    }","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-cos/src/main/java/org/apache/hadoop/fs/cosn/CosNInputStream.java#L257-L293","documentation":"Thrown by CosNInputStream.read() (single-byte variant) when the stream's closed flag is already set. Like all CosN read-path methods, it refuses any I/O after close() and surfaces the shared Hadoop message FSExceptionMessages.STREAM_IS_CLOSED. It indicates the caller kept or reused a stream reference after closing it (or after a framework helper like IOUtils.closeQuietly closed it).","triggerScenarios":"Calling read() on a CosNInputStream after close() ran; typical shapes: close() in a finally block that also falls through to more reads, two code paths closing the same FSDataInputStream (double close is harmless, but read-after-second-close is not), or a reader thread racing a closer thread.","commonSituations":"Utility wrappers (e.g., custom RecordReader) that close the inner stream in nextKeyValue() but keep reading; retry loops that close the stream on first error then unconditionally read in a catch/finally block; caching layers that evict (and close) entries while another consumer still reads.","solutions":["Restructure ownership: exactly one component owns close(), and no read is issued after that component's lifecycle ends.","Set the reference to null immediately after close() so a second use fails fast with NPE at the correct call site instead of this message.","If multiple consumers share one stream, wrap it in a ref-counted stream (e.g., a FilterInputStream with an acquire/release count) and close only when the count hits zero.","In concurrent code, synchronize or use an AtomicBoolean closed flag checked before every read; interrupt/await the reader before closing."],"exampleFix":"// before\ntry {\n  return in.read();\n} finally {\n  in.close();   // next call to read() throws 'Stream is closed!'\n}\n\n// after\ntry {\n  return in.read();\n} finally {\n  in.close();\n  in = null;    // fail fast with NPE if read is attempted later\n}","handlingStrategy":"validation","validationCode":"if (in == null) throw new IllegalStateException(\"stream already closed\");\n// own flag when ownership is shared:\n// if (!open.get()) throw new IllegalStateException(...);\nint b = in.read();","typeGuard":null,"tryCatchPattern":"catch (IOException e) {\n  if (FSExceptionMessages.STREAM_IS_CLOSED.equals(e.getMessage())) {\n    // lifecycle bug: reopen and replay the range from a known offset\n    in = fs.open(path); in.seek(lastGoodPos);\n  } else { throw e; }\n}","preventionTips":["Null the stream reference immediately after close().","One owner for close(); never share a stream across tasks without ref-counting.","Finish all reads before the finally block that closes."],"tags":["cosn","tencent-cos","input-stream","lifecycle","closed-stream"],"backgroundTag":"read-after-close","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}