apache/hadoop · error · IOException

{}: Stream is closed!

Error message

{}: Stream is closed!

What it means

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.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/sftp/SFTPInputStream.java:137

    }
    if (stats != null & byteRead >= 0) {
      stats.incrementBytesRead(1);
    }
    return byteRead;
  }

  public synchronized void close() throws IOException {
    if (closed) {
      return;
    }
    super.close();
    wrappedStream.close();
    closed = true;
  }

  private void checkNotClosed() throws IOException {
    if (closed) {
      throw new IOException(
          path.toUri() + ": " + FSExceptionMessages.STREAM_IS_CLOSED
      );
    }
  }
}

View on GitHub (pinned to 2add963021)

Solutions

  1. Null out the reference after closing and guard every use: if (in != null) in.read(...).
  2. When data is needed again, reopen with fs.open(path) instead of reusing the closed stream.
  3. Establish single ownership: either the framework or your code closes the stream, never both.

Example fix

// before
try (FSDataInputStream in = fs.open(p)) {
  header = readHeader(in);
} // in closed here
int b = in.read(); // IOException: Stream is closed!

// after
byte[] header;
try (FSDataInputStream in = fs.open(p)) {
  header = readHeader(in);
}
// need more data -> open a new stream
try (FSDataInputStream in2 = fs.open(p)) {
  in2.seek(header.length);
  // ...
}
Defensive patterns

Strategy: validation

Try / catch

try {
  int b = in.read();
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().contains("Stream is closed")) {
    in = fs.open(path); // reopen instead of reusing the closed stream
    int b = in.read();
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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