This episode teaches a structured approach when pgBackRest has problems: raising the log level with --log-level-console=debug and --log-level-file=debug, reading /var/log/pgbackrest/, and handling the four most common cases — failed archive-push, permission denied, full repository, and version mismatch.

In episode 14 we installed alarms — now it's time to learn what happens when the alarm rings. pgBackRest is a very communicative tool: it writes detailed logs to files and can display full debug output on the console. The real problem isn't "an error appeared," but reading the error correctly — and in episode 15 we train that with the four most common cases in the field.
The mindset to hold: every pgBackRest error names the file and process involved. Good debugging is following that trail, not guessing.
pgBackRest has two log paths: console (stdout/stderr when a command runs) and file (in /var/log/pgbackrest/). Both can have their levels set independently:
sudo -u postgres pgbackrest --stanza=main --log-level-console=debug backup --type=diffsudo -u postgres pgbackrest --stanza=main --log-level-file=debug backup --type=diffAvailable levels: off, error, warn, info, detail, debug, trace. For troubleshooting, debug is usually enough; trace is very verbose and only for extreme cases.
Tip
Use --log-level-console=debug for interactive incidents and --log-level-file=debug for long-running investigations. In production, don't leave log-level-file=debug permanently — the logs will bloat. Raise it during an investigation, lower it when done.
Log files are stored per process with a name containing the timestamp and PID:
ls -lt /var/log/pgbackrest/
sudo tail -50 /var/log/pgbackrest/pgbackrest-20260813-120000.logThe log line format: level, process (P00 = master, P01+ = worker), and message. Note the following patterns on error:
P00 ... ERROR: [046]: ... — error with a code; [046] etc. are categories documented at pgbackrest.org.P01 ... ERROR: ... while processing file ... — indicates the specific file that failed.DETAIL and HINT lines — explanation and suggested fix.WAL never reaches the repository; pg_stat_archiver.failed_count rises; check fails at the archive-push part.
sudo -u postgres pgbackrest --stanza=main --log-level-console=debug check
tail -30 /var/log/postgresql/*.log | grep -i archiveThe most common errors and their fixes:
archive_command has the wrong binary path: make sure pgbackrest is in the postgres user's PATH, or write an absolute path.archive_command isn't enabled: archive_mode=on needs a restart (episode 6).stanza-create first.If the error mentions a code and a WAL file, test archive-push manually with a test file:
sudo -u postgres pgbackrest --stanza=main archive-push /var/lib/postgresql/16/main/pg_wal/0000000100000000000000FFpermission denied appears in the logs — usually when a backup is first run as the wrong user, or after a directory has been recreated.
ls -ld /var/lib/pgbackrest /var/lib/pgbackrest/backup /var/log/pgbackrest
ls -ld /var/lib/postgresql/16/mainThe fix:
sudo chown -R postgres:postgres /var/lib/pgbackrest
sudo chown -R postgres:postgres /var/log/pgbackrestRunning pgbackrest as root for a local backup. When archive-push is run by the server (the postgres user), access to a repository created by root actually fails. Always be consistent: local backup = the postgres user, or a dedicated user with the same repository access.
Warning
A permission denied that "comes and goes" is usually about different users: a backup succeeds when run manually as postgres, but fails from cron because of a different user or PATH. Make sure the schedule (episode 10) uses the same user as your manual testing.
archive-push starts failing; df -h shows the repository at 100%. Backups fail midway because there's no space.
repo1-retention-archive isn't applied (episode 10)..tmp files from interrupted backups can clog up space:sudo find /var/lib/pgbackrest -name "*.tmp" -size +100Marchive-push operations are automatically retried by PostgreSQL — failed WAL isn't lost, it's just waiting.Errors like db version ... does not match ... or stanza already exists. These appear when the pgBackRest or PostgreSQL version doesn't match what's recorded in the stanza.
stanza-upgrade to update the stanza metadata:sudo -u postgres pgbackrest --stanza=main stanza-upgradecheck after the upgrade.Note
The most confusing version mismatch usually happens after a restore: the old config in PGDATA (the restore result) isn't in sync with the new environment. Always compare pgbackrest version on both sides and the cluster identity via pgbackrest info after a restore.
When an error comes, follow this sequence without skipping:
--log-level-console=debug./var/log/pgbackrest/ for context not visible on the console.Key takeaways:
--log-level-console=debug for interactive incidents; --log-level-file=debug for long investigations./var/log/pgbackrest/ contain error codes, DETAIL, and HINT.archive_mode, and the stanza..tmp.stanza-upgrade for a PostgreSQL upgrade; never force-delete a stanza.In the next episode we'll prove your backups can actually be recovered: restore testing (drills) — doing periodic restore tests to a separate instance, validating data (checksums, row counts), automating the drill with scripts + reports, and documenting the runbook. A backup that was never tested is hope disguised as a plan!