tar: file changed as we read it (cron backup fix)
A nightly tar job exits 1 and prints tar: site/access.log: file changed as we read it even though nothing is broken. The archive is usually valid and the message informational — but how your cron wrapper reads that exit code decides whether you get a silent gap in your backups or an alert you will eventually mute. This post measures what the message means on GNU tar 1.35, what each "silencer" flag does to the exit status, and which fix removes the race instead of hiding it.
Prerequisites: a Linux host with GNU tar (these flags are GNU-specific; BusyBox tar and bsdtar differ), a cron or systemd timer you can edit, and shell access to the directory being archived. Everything quoted ran on Linux 6.17.0-1019-oracle, aarch64, GNU tar 1.35 — the tar transcript on 20 October 2026, the audit and wrapper runs on 21 October.
TL;DR — exit 1 means "one file moved", not "backup failed"
file changed as we read itis a warning: tar recorded the size when it opened the file, copied that many bytes, then re-stat'ed and found the size or mtime had moved. Exit status 1.- Exit 2 is the fatal one (“Error is not recoverable”): bad archive path, unreadable directory, I/O error.
--warning=no-file-changedhides the text and leaves exit 1 — evidence removed, monitoring still paging.--ignore-failed-readdoes the reverse: exit 0, warning kept.tar -cf - … | gzipwithoutpipefailreturns 0 while tar returned 1:rc=0withoutset -o pipefail,rc=1with it.copytruncateproduces a different message —File shrank by N bytes; padding with zeros, which--warning=no-file-changeddoes not silence.- The archive is not corrupt: it holds exactly the bytes tar saw, short only of the tail written after
fstat()— 46 bytes in the run below.