Standard Error
Standard error (stderr, file descriptor 2 on Unix and STD_ERROR_HANDLE on Windows) is the secondary output stream reserved for error messages, warnings, progress bars, and diagnostic logs (eprint!, eprintln!, dbg!). Separating diagnostic messages onto stderr keeps stdout clean when users pipe or redirect program output (my_app > output.json).
Comparing Stdout (FD 1) and Stderr (FD 2)
CLI Pipeline Separation (`my_program > data.json`):
+--------------+ stdout (fd 1: JSON data) +-----------------+
| my_program | --------------------------> | data.json |
| | stderr (fd 2: warnings) +-----------------+
| | --------------------------> [ User's Terminal ]
+--------------+
| Property | Standard Output (Stdout, FD 1) |
Standard Error (Stderr, FD 2) |
|---|---|---|
| Intended content | Primary machine/data output (JSON, CSV, results) |
Errors, warnings, progress indicators, dbg! logs |
| Default buffering in Rust | Line-buffered (LineWriter) |
Unbuffered (every write goes directly to OS fd 2 immediately!) |
| Formatting macros | print!, println! |
eprint!, eprintln!, dbg! |
| Shell redirection | > file.txt or | next_cmd |
2> err.log (or 2>&1 to merge with stdout) |
Why Stderr Is Unbuffered by Default
If a program crashes or aborts immediately after logging an error message (even without a trailing \n), an unbuffered Stderr guarantees the diagnostic bytes have already been handed to the OS kernel and appear on the terminal rather than sitting lost inside a user-space RAM buffer.
When emitting a large multi-part diagnostic block to stderr where you want all lines to appear atomically without interleaving from other threads, lock io::stderr().lock() and use writeln!:
use std::io::{self, Write};
fn report_diagnostic(code: u16, detail: &str) -> io::Result<()> {
let mut err_lock = io::stderr().lock();
writeln!(err_lock, "[WARN E{code:04}] {detail}")?;
Ok(())
}
fn main() -> io::Result<()> {
// Primary data goes to stdout:
println!("{{\"status\":\"ok\"}}");
// Diagnostic warning goes to stderr:
report_diagnostic(401, "using fallback configuration")?;
Ok(())
}
{"status":"ok"}
[WARN E0401] using fallback configuration