stamparm/maltrail · error
short write to the event log
Error message
short write to the event log ({n} of {} bytes); the record may be truncated What it means
A write to the event log wrote fewer bytes than the serialized event line, meaning the record may be truncated on disk. The code performs a single write(2) per event (relying on O_APPEND atomicity) and deliberately treats a short write as an error instead of looping, because the append size bound makes partial writes abnormal.
Solutions
- Check disk space on the event log filesystem (df -h) and free space or rotate the log.
- Ensure the event log path is a regular file on local storage, not a pipe or network mount.
- Reduce event line size (payload truncation settings) if events are extremely large.
- Treat affected records as suspect: inspect the log tail and re-verify events around the error timestamp.
Defensive patterns
Strategy: validation
Validate before calling
// ensure the log target is a regular file on a filesystem with headroom
let md = std::fs::metadata(log_path)?;
if !md.is_file() { eprintln!("event log must be a regular file"); }
let free = fs4::available_space(log_path)?;
if free < 64 * 1024 * 1024 { eprintln!("low disk space for event log"); } Prevention
- Keep headroom on the event log filesystem and rotate logs proactively
- Keep event line sizes bounded (payload truncation settings)
- Avoid pointing the event log at pipes or network filesystems
- Watch for short-write log lines and investigate immediately
When it happens
Trigger: file.write(line.as_bytes()) returns Ok(n) where n < line.len() during write_event_log. Typically only when the write exceeds the pipe/append size bound or the disk fills mid-write.
Common situations: Very large event lines combined with a full or nearly full filesystem; writes to a log on a pipe/special file rather than a regular file; kernel resource pressure interrupting large writes.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- unable to open event log
- unable to write event log
- invalid configuration value for 'LOG_SERVER
- invalid configuration value for 'LOCAL_LOG_FORMAT
- create log dir
AI-assisted analysis of stamparm/maltrail@77cfb06d76 (2026-09-13).
Data as JSON: /api/errors/644041b2cf0caf9c.
Report an issue: GitHub.
Appendix: source
Thrown at sensor/src/output.rs:367
}
if let Some(file) = self.log_file.as_mut() {
// ONE write(2) per event, deliberately — not `write_all`.
//
// The guarantee that matters with several workers appending to one file is that each
// event line lands whole: O_APPEND makes the kernel pick the append offset and perform
// the copy atomically *per system call*, so one call per line means workers interleave
// whole records. `write_all` loops on a short write, which would split a line across
// two calls and let another worker's line land in the middle of it.
//
// (An earlier comment here justified this with PIPE_BUF. That was wrong: PIPE_BUF
// bounds atomic writes to PIPES, not regular files. The property being relied on is
// O_APPEND's atomic offset-plus-write, which has no such size bound in practice but is
// also not unlimited — hence treating a short write as an error rather than looping.)
match file.write(line.as_bytes()) {
Ok(n) if n == line.len() => {}
Ok(n) => {
self.log_write_errors += 1;
log_error(
&format!(
"short write to the event log ({n} of {} bytes); the record may be truncated",
line.len()
),
true,
)
}
Err(e) => {
self.log_write_errors += 1;
log_error(&format!("unable to write event log ({e})"), true)
}
}
}
}
/// Matched against "<info> <reference>". Whether a verdict was corroborated lives in the
/// reference, and REMOTE_SEVERITY_REGEX has to see it to rank a heuristic guess below a feed
/// hit the way the dashboard does - `core/log.py:severity_of()` does the same.View on GitHub (pinned to 77cfb06d76)