apache/hadoop · error · IOException

Stream is closed!

Error message

Stream is closed!

What it means

ByteBufferInputStream serves reads directly from a java.nio.ByteBuffer; close() releases the reference. verifyOpen() then throws IOException('Stream is closed!') from read/skip paths invoked after close. The public synchronized isOpen() method is the supported test for this state.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/store/ByteBufferInputStream.java:81

    LOG.debug("ByteBufferInputStream.close()");
    byteBuffer = null;
  }

  /**
   * Is the stream open?
   * @return true if the stream has not been closed.
   */
  public synchronized boolean isOpen() {
    return byteBuffer != null;
  }

  /**
   * Verify that the stream is open.
   * @throws IOException if the stream is closed
   */
  private void verifyOpen() throws IOException {
    if (byteBuffer == null) {
      throw new IOException(FSExceptionMessages.STREAM_IS_CLOSED);
    }
  }

  /**
   * Check the open state.
   * @throws IllegalStateException if the stream is closed.
   */
  private void checkOpenState() {
    Preconditions.checkState(isOpen(),
        FSExceptionMessages.STREAM_IS_CLOSED);
  }

  public synchronized int read() throws IOException {
    if (available() > 0) {
      return byteBuffer.get() & 0xFF;
    } else {
      return -1;
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Check isOpen() before each access on streams whose lifecycle you do not own
  2. Restructure so a single owner closes the stream after all readers finish
  3. Open a fresh stream over the buffer for the next pass instead of reusing the closed one

Example fix

// before
in.close();
int b = in.read(); // IOException: Stream is closed!

// after
in.close();
if (in.isOpen()) {
  int b = in.read();
}
Defensive patterns

Strategy: validation

Validate before calling

ByteBufferInputStream in = ...;
if (in.isOpen()) {
  int b = in.read();
}

Try / catch

Catch IOException and compare against FSExceptionMessages.STREAM_IS_CLOSED; treat a match as a lifecycle bug in the caller (read-after-close), not a transient failure — do not retry.

Prevention

When it happens

Trigger: Any read()/skip()/position() call after close(); retry logic that closes the stream in a finally block and keeps reading; one thread closing while another reads.

Common situations: Use-after-close in cleanup paths; streams shared across components where each thinks it owns closing; defensive double-close followed by reads.

Related errors


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