uutils/coreutils · error · std::io::Error
head-error-writing-stdout
Error message
head-error-writing-stdout
What it means
`head` wraps any `io::Error` raised while writing parsed content to stdout, replacing the message with a localized `head-error-writing-stdout` that embeds the stripped errno text, while preserving the original error kind. It tells the user the failure happened at the output stage, not while reading input.
Solutions
- Check the shell pipeline: ensure the consumer of head's output is alive and reading
- Redirect to a writable destination (`df -h` to confirm free space; test with `> /tmp/out`)
- If SIGPIPE from early reader exit is expected, ignore it (exit 141 is normal)
- Run without redirection to verify stdout itself works
Example fix
// before head -n 100 log.txt > /dev/full // after head -n 100 log.txt > output.txt
Defensive patterns
Strategy: try-catch
Validate before calling
[ -w "$(dirname "$out")" ] && df -h --output=avail "$out" | awk 'NR==2 && $1+0>0' || echo 'stdout target not writable'
Type guard
fn is_stdout_writable() -> bool {
use std::io::Write;
std::io::stdout().flush().is_ok()
} Try / catch
match result {
Err(e) if e.kind() == ErrorKind::BrokenPipe => { /* consumer exited early: ignore */ }
Err(e) => { eprintln!("head: error writing stdout: {}"); exit(1); }
Ok(()) => {}
} Prevention
- Ensure pipeline consumers stay alive until head finishes
- Avoid redirecting to /dev/full or full filesystems
- Check downstream commands in CI pipelines for early exit
- Remember exit code 141/EPIPE on pipes is often benign
When it happens
Trigger: Writing the first N lines/bytes to stdout fails, e.g. `head big.txt | head -c 100 > /dev/full`, a closed pipe (`head f | true`), or a full disk / EPIPE on the terminal.
Common situations: Piping into `head`-terminated pipelines where the downstream reader exits early (SIGPIPE handling), redirecting to `/dev/full`, or writing to a read-only/closed descriptor.
Related errors
AI-assisted analysis of uutils/coreutils@92995feca2 (2026-09-20).
Data as JSON: /api/errors/cdc00921cc789ffd.
Report an issue: GitHub.
Appendix: source
Thrown at src/uu/head/src/head.rs:209
verbose: matches.get_flag(options::VERBOSE),
line_ending: LineEnding::from_zero_flag(matches.get_flag(options::ZERO)),
presume_input_pipe: matches.get_flag(options::PRESUME_INPUT_PIPE),
mode: Mode::from(matches)?,
// #[allow(clippy::unwrap_used, reason = "clap provides '-' by default")] <https://github.com/rust-lang/rust/issues/15701>
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 92995feca2)