apache/flink · error · IOException
Stream closed.
Error message
Stream closed.
What it means
Thrown by RefCountedBufferingFileStream.requireOpen() when any operation (write/flush/getPos) is attempted on a stream whose `closed` flag is true. It is the standard 'use after close' guard for this buffering temp file stream.
Source
Thrown at flink-core/src/main/java/org/apache/flink/core/fs/RefCountedBufferingFileStream.java:141
if (!closed) {
currentTmpFile.closeStream();
closed = true;
}
}
@Override
public void retain() {
currentTmpFile.retain();
}
@Override
public boolean release() {
return currentTmpFile.release();
}
private void requireOpen() throws IOException {
if (closed) {
throw new IOException("Stream closed.");
}
}
@Override
public String toString() {
return "Reference Counted File with {"
+ "path=\'"
+ currentTmpFile.getFile().toPath().toAbsolutePath()
+ "\'"
+ ", size="
+ getPos()
+ ", reference counter="
+ currentTmpFile.getReferenceCounter()
+ ", closed="
+ closed
+ '}';
}
View on GitHub (pinned to 2f3c205e92)
Solutions
- Track ownership: ensure only one code path closes the stream, and no writes follow it.
- Reset the reference to null after close and null-check before use.
- Use try-with-resources or a lifecycle wrapper that guarantees write/close ordering.
- In failure handlers, set a flag and skip subsequent write/flush operations.
Example fix
// before
stream.write(buffer);
stream.close();
stream.flush(); // throws
// after
stream.write(buffer);
stream.close();
// no further operations; or guard:
if (!stream.isClosed()) { stream.flush(); } Defensive patterns
Strategy: validation
Validate before calling
void safeFlush(RefCountedBufferingFileStream s) throws IOException {
if (s.isClosed()) return; // or throw IllegalStateException
s.flush();
} Try / catch
try {
stream.flush();
} catch (IOException e) {
if ("Stream closed.".equals(e.getMessage())) { /* already closed, ignore */ return; }
throw e;
} Prevention
- Establish single ownership of stream close.
- Set the reference to null after close and null-check before use.
- Order cleanup so writes always precede close.
When it happens
Trigger: Calling write(), flush(), or getPos() on a RefCountedBufferingFileStream after close() has been invoked; double-close paired with a subsequent operation; an exception in one branch leaving the stream closed while another code path keeps writing.
Common situations: Sink writer cleanup paths; concurrent close+write during task failure/cancellation; error-handling code that closes on failure but a finally block still attempts to flush.
Related errors
- Stream closed.
- Stream closed.
- URL is invalid. This should not happen.
- An I/O error occurred while creating temporary file to extra
- Exception encountered during finding the flink-python jar. T
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/b6a53a9e33d50b62.
Report an issue: GitHub.