Docker "write /dev/stdout: broken pipe" in CI
A "broken pipe" on /dev/stdout means the reader on the other end of the pipe closed before the container finished writing. In CI this commonly comes from a piped consumer (head, a log forwarder, the runner stream) that exited or was torn down, or a transient stream drop. It is usually a stream-lifecycle issue, not a defect in the containerized program.
What this error means
A container or docker logs command prints write /dev/stdout: broken pipe and the step fails, often when the output was piped into another command that closed early.
write /dev/stdout: broken pipeCommon causes
A downstream consumer closed the pipe
Piping into head, grep -q, or a tool that exits after the first match closes stdout while the producer keeps writing.
The runner stream was torn down
A cancelled or timed-out job tears down the log stream mid-write.
A transient stream drop
An ephemeral disconnect of the attached output stream surfaces as EPIPE.
How to fix it
Tolerate early pipe closure
- If you intentionally truncate output, ignore the resulting EPIPE in the producer.
- Avoid piping long-running container logs into commands that exit early.
docker logs myservice 2>&1 | grep -m1 "ready" || trueWrite to a file instead of a fragile pipe
- Capture container output to a file and scan the file, so a reader exit never EPIPEs the producer.
docker logs -f myservice > app.log 2>&1 &
sleep 2 && grep -q "ready" app.logHow to prevent it
- Avoid piping unbounded container output into early-exit consumers.
- Capture logs to a file when you only need to scan for a marker.