SQLSTATE XX001 — PANIC: Could Not Write to pg_wal
! Symptoms Free
Conditions:
- PostgreSQL log:
PANIC: could not write to file "pg_wal/..."withNo space left on device - All connections abruptly dropped
df -hshows 100% on the WAL partition (or data partition if they share)- PostgreSQL will not restart until space is freed
- Inactive replication slots are often the cause of pg_wal growth
1 Environment & reproduce Free
Difficulty: Advanced | PostgreSQL versions: 12, 13, 14, 15, 16, 17
? Root cause Free
- The only safe immediate action when pg_wal is full: free space by dropping inactive replication slots — do NOT delete files from pg_wal manually.
max_wal_sizecontrols checkpoint frequency, not disk usage when replication slots hold WAL.max_slot_wal_keep_size(PG13+) is the prevention: limits WAL a slot can retain before it's invalidated.- After freeing space, PostgreSQL recovers automatically on restart — crash recovery replays the WAL.
- If both
pg_walandpg_baseare on the same volume, temp files or table growth may also fill it. - Never set
wal_keep_sizehigh without also settingmax_slot_wal_keep_size.
Free space by dropping inactive replication slots. Set max_slot_wal_keep_size to prevent recurrence. Restart PostgreSQL — crash recovery is automatic.
2 Diagnose Free
RESULT-- BEFORE restart (investigate cause):
-- df -h $PGDATA ← is disk actually full?
-- du -sh $PGDATA/pg_wal/ ← WAL directory size
-- ls $PGDATA/pg_wal/*.history ← timeline files
-- du -sh $PGDATA/pg_wal/*.* | sort -h | tail -20
-- Check replication slots (common culprit):
SELECT slot_name, active, wal_status,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flushed_lsn))
AS retained_wal
FROM pg_replication_slots
ORDER BY confirmed_flushed_lsn;
-- inactive slots with large retained_wal = cause of disk full🔒 Diagnose deeper Pro
Find every latent occurrence before it ships
The steps above clear this incident. Pro adds the executed, verified depth that stops the whole class of bug across your fleet.
- ✓Catalog & log queries that surface every at-risk object before a migration ships.
- ✓Inspect-without-running tricks (
\gdescand friends). - ✓Exactly where the log line surfaces on RDS, Azure & Cloud SQL.
- ✓Cross-version gotchas, verified on PostgreSQL 14–18.
Every Pro query on this site is executed against real PostgreSQL and verified — we never publish an untested snippet.
Already a member? Log in
3 Recovery & verify Free
Free space by dropping inactive replication slots. Set max_slot_wal_keep_size to prevent recurrence. Restart PostgreSQL — crash recovery is automatic.