TheAlgorithms/Java · error · IllegalStateException

Input Stream already closed!

Error message

Input Stream already closed!

What it means

BufferedReader.assertStreamOpen throws IllegalStateException (an unchecked exception) when input == null, which happens after close() sets the field to null. Any operation on a closed reader (read, peek, available, refill) triggers this via assertStreamOpen. This is the standard 'use after close' guard.

Source

Thrown at src/main/java/com/thealgorithms/io/BufferedReader.java:184

        // try to fill in the maximum we can until
        // we reach EOF
        while (bufferPos < bufferSize) {
            int read = input.read();
            if (read == -1) {
                // reached end-of-file, no more data left
                // to be read
                foundEof = true;
                // rewrite the BUFFER_SIZE, to know that we've reached
                // EOF when requested refill
                bufferSize = bufferPos;
            }
            buffer[bufferPos++] = (byte) read;
        }
    }

    private void assertStreamOpen() {
        if (input == null) {
            throw new IllegalStateException("Input Stream already closed!");
        }
    }

    public void close() throws IOException {
        if (input != null) {
            try {
                input.close();
            } finally {
                input = null;
            }
        }
    }
}

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Do not use the reader after close(); structure code so close() is the last operation (try-with-resources is ideal).
  2. If sharing a reader, coordinate ownership so only one caller closes it, after all readers finish.
  3. Track closed state in your own flag and check before delegating if lifecycle is complex.

Example fix

// before
BufferedReader r = new BufferedReader(stream);
String line = readAll(r);
r.close();
int b = r.read(); // IllegalStateException

// after
try (BufferedReader r = new BufferedReader(stream)) {
    String line = readAll(r);
} // closed automatically; no use after
Defensive patterns

Strategy: try-catch

Try / catch

// IllegalStateException is unchecked; catch only if you must tolerate use-after-close.
try {
    int b = reader.read();
} catch (IllegalStateException e) {
    // reader was closed; reopen or report
    log.warn("reader already closed", e);
}

Prevention

When it happens

Trigger: Calling read(), peek(), readBlock(), or any read-driving method on a BufferedReader after close() was already called. close() nulls out the input field, and the next operation asserts it is non-null.

Common situations: Try-with-resources where the reader is used after the block, a manual close() followed by a read in an error path, or shared reader instances where one caller closes it and another continues.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/e12924072b40d16a. Report an issue: GitHub.