apache/flink · error · IOException
Unable to write to output stream.
Error message
Unable to write to output stream.
What it means
IOUtils.copyBytes treats the output stream specially when it is a PrintStream: PrintStream swallows I/O errors, so after each write the code calls ps.checkError() and throws IOException("Unable to write to output stream.") if the underlying stream failed. Without this the copy would silently produce truncated output.
Source
Thrown at flink-core/src/main/java/org/apache/flink/util/IOUtils.java:66
* @param out OutputStream to write to
* @param buffSize the size of the buffer
* @param close whether or not close the InputStream and OutputStream at the end. The streams
* are closed in the finally clause.
* @throws IOException thrown if an error occurred while writing to the output stream
*/
public static void copyBytes(
final InputStream in, final OutputStream out, final int buffSize, final boolean close)
throws IOException {
@SuppressWarnings("resource")
final PrintStream ps = out instanceof PrintStream ? (PrintStream) out : null;
final byte[] buf = new byte[buffSize];
try {
int bytesRead = in.read(buf);
while (bytesRead >= 0) {
out.write(buf, 0, bytesRead);
if ((ps != null) && ps.checkError()) {
throw new IOException("Unable to write to output stream.");
}
bytesRead = in.read(buf);
}
} finally {
if (close) {
out.close();
in.close();
}
}
}
/**
* Copies from one stream to another. <strong>closes the input and output streams at the
* end</strong>.
*
* @param in InputStream to read from
* @param out OutputStream to write to
* @throws IOException thrown if an I/O error occurs while copyingView on GitHub (pinned to 2f3c205e92)
Solutions
- Check what consumed the process stdout — a closed pipe on the reader side is the usual cause; keep the consumer alive or buffer output
- Write to a regular FileOutputStream/BufferedOutputStream instead of a PrintStream so failures surface as normal IOExceptions with a cause
- If truncation is acceptable (e.g. piping into head), catch this IOException and ignore it deliberately
Example fix
// before
IOUtils.copyBytes(in, System.out, 4096, false);
// after (failures carry a real cause)
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
IOUtils.copyBytes(in, out, 4096, true);
} Defensive patterns
Strategy: try-catch
Try / catch
try { IOUtils.copyBytes(in, System.out, 4096, false); } catch (IOException e) { /* reader closed the pipe (e.g. | head): exit quietly */ } Prevention
- Prefer real output streams over PrintStream for programmatic copies
- When piping CLI output to short-lived consumers, tolerate this error explicitly
When it happens
Trigger: Calling IOUtils.copyBytes with System.out/System.err or another PrintStream as destination whose sink has failed — e.g. the pipe reading the process output closed (head/broken less), a redirected stdout to a full/closed file, or a dead terminal on the other end.
Common situations: CLI jobs piping Flink output into `head`, log redirection where the disk filled, running in containers where stdout is drained by a logger daemon that died.
Related errors
- Premature EOF from inputStream
- Premeture EOF from inputStream
- Stream is closed
- Stream is already closed
- Error while waiting for job to be initialized
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/a57edade899677a6.
Report an issue: GitHub.