uutils/coreutils · warning · io::Error
head-error-writing-stdout
Error message
head-error-writing-stdout
What it means
head wraps any I/O error that occurs while writing output to stdout with this 'error writing stdout' message, preserving the original error kind and appending the stripped errno text. It distinguishes failures on the output side (broken pipe, full disk) from failures reading the input files.
Source
Thrown at src/uu/head/src/head.rs:209
options.verbose = matches.get_flag(options::VERBOSE);
options.line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO));
options.presume_input_pipe = matches.get_flag(options::PRESUME_INPUT_PIPE);
options.mode = Mode::from(matches)?;
// #[allow(clippy::unwrap_used, reason = "clap provides '-' by default")] <https://github.com/rust-lang/rust/issues/15701>
options.files = matches
.get_many::<OsString>(options::FILES)
.unwrap()
.cloned()
.collect();
Ok(options)
}
}
#[inline]
fn wrap_in_stdout_error(err: io::Error) -> io::Error {
io::Error::new(
err.kind(),
translate!("head-error-writing-stdout", "err" => uucore::error::strip_errno(&err)),
)
}
// zero-copy fast-path
#[cfg(any(target_os = "linux", target_os = "android"))]
fn print_n_bytes(input: impl AsFd, n: u64) -> io::Result<u64> {
let out = io::stdout();
uucore::pipes::send_n_bytes(input, &out, n).map_err(wrap_in_stdout_error)
}
#[cfg(not(any(target_os = "linux", target_os = "android")))]
fn print_n_bytes(input: impl Read, n: u64) -> io::Result<u64> {
// Read the first `n` bytes from the `input` reader.
let mut reader = input.take(n);
// Write those bytes to `stdout`.View on GitHub (pinned to 325183372a)
Solutions
- Ignore it if caused by a downstream `head`/`q` closing the pipe — this is expected SIGPIPE/EPIPE behavior; ensure your script tolerates non-zero exit
- Check available space with `df` if stdout is redirected to a file and free space on the target filesystem
- Verify the consuming process in the pipeline is still alive and reads the data
- Handle SIGPIPE in the surrounding shell script (set -o pipefail considerations)
Example fix
// before head -n 1000 huge.log > /mnt/full-disk/out.txt // after df -h /mnt/full-disk # ensure space first head -n 1000 huge.log > /mnt/full-disk/out.txt || echo "stdout write failed: $?"
Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
// treat EPIPE on stdout as benign in pipelines
head -n 100 huge.log | head -n 5
if [ ${PIPESTATUS[0]} -ne 0 ]; then
case $(head -n 100 huge.log 2>&1 >/dev/null) in
*"error writing stdout"*) echo "benign broken pipe" ;;
esac
fi Prevention
- Expect nonzero exits when head's output is consumed by something that exits early
- Check `df` before redirecting large outputs to disk
- Use `set +o pipefail` (or handle PIPESTATUS) for pipelines where early exit is intentional
When it happens
Trigger: head writes lines/bytes to stdout and the write fails — typically EPIPE when stdout is piped into a consumer that exits early (e.g., `head big | head -1` chains), or ENOSPC when stdout is redirected to a full disk/device.
Common situations: Piping head into commands like `less` then quitting, `| head` in scripts where downstream commands close the pipe, redirecting output to a full filesystem or a closed socket.
Related errors
AI-assisted analysis of uutils/coreutils@325183372a (2026-08-31).
Data as JSON: /api/errors/cdc00921cc789ffd.
Report an issue: GitHub.