{"record":{"id":"2d31c8fa4221300a","repo":"apache/hadoop","slug":"stream-is-closed-2d31c8","errorCode":null,"errorMessage":"{}: Stream is closed!","messagePattern":"(.+?): Stream is closed!","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/sftp/SFTPInputStream.java","lineNumber":137,"sourceCode":"    }\n    if (stats != null & byteRead >= 0) {\n      stats.incrementBytesRead(1);\n    }\n    return byteRead;\n  }\n\n  public synchronized void close() throws IOException {\n    if (closed) {\n      return;\n    }\n    super.close();\n    wrappedStream.close();\n    closed = true;\n  }\n\n  private void checkNotClosed() throws IOException {\n    if (closed) {\n      throw new IOException(\n          path.toUri() + \": \" + FSExceptionMessages.STREAM_IS_CLOSED\n      );\n    }\n  }\n}\n","sourceCodeStart":119,"sourceCodeEnd":143,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/sftp/SFTPInputStream.java#L119-L143","documentation":"SFTPInputStream.checkNotClosed (SFTPInputStream.java:135) throws IOException 'path: Stream is closed!' when read, seek, available, or related operations run after the stream's close() completed (the closed flag is set). close() itself is idempotent — early-returns if already closed — but any subsequent data operation fails.","triggerScenarios":"Calling read()/seek()/available()/getPos() on a stream whose close() already ran; a helper reading from a stream inside try-with-resources scope after the block exited; a wrapper stream that closed the underlying SFTPInputStream early.","commonSituations":"Two owners of the same stream (framework closes it in a committer, user code reads afterwards); finally-blocks closing the stream before a later retry reuses the reference; one thread closing while another thread is mid-read.","solutions":["Null out the reference after closing and guard every use: if (in != null) in.read(...).","When data is needed again, reopen with fs.open(path) instead of reusing the closed stream.","Establish single ownership: either the framework or your code closes the stream, never both."],"exampleFix":"// before\ntry (FSDataInputStream in = fs.open(p)) {\n  header = readHeader(in);\n} // in closed here\nint b = in.read(); // IOException: Stream is closed!\n\n// after\nbyte[] header;\ntry (FSDataInputStream in = fs.open(p)) {\n  header = readHeader(in);\n}\n// need more data -> open a new stream\ntry (FSDataInputStream in2 = fs.open(p)) {\n  in2.seek(header.length);\n  // ...\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  int b = in.read();\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Stream is closed\")) {\n    in = fs.open(path); // reopen instead of reusing the closed stream\n    int b = in.read();\n  } else {\n    throw e;\n  }\n}","preventionTips":["Scope stream usage strictly inside its try-with-resources block.","Null the reference after close and check for null before reads.","Give the stream one owner; do not let frameworks and user code both close it."],"tags":["sftp","stream-closed","input-stream","hadoop","io"],"backgroundTag":"resource-already-closed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}