SQLSTATE XX000 ERROR Class XX: Internal Error

internal_error database is not accepting commands to avoid wraparound data loss — XX000

PostgreSQL error “database is not accepting commands to avoid wraparound data loss — XX000” (SQLSTATE XX000): what it means, common causes, and how to fix it.

PG 9.6, 10, 11, 12, 13, 14, 15, 16, 17, 18 Official docs
Last reviewed Jun 2026 Grounded in source

Diagnostic Queries

Symptoms

PostgreSQL has stopped accepting commands that assign new transaction IDs to prevent data loss from transaction-ID wraparound. It reports SQLSTATE XX000 (internal_error) for write attempts.

  • The database refuses new write transactions.
  • A protective measure against wraparound data loss.
  • Single-user VACUUM is required to recover.

What the server log shows

ERROR:  database is not accepting commands to avoid wraparound data loss in database "production"
HINT:  Stop the postmaster and vacuum that database in single-user mode.

Why PostgreSQL raises this — what the manual says

Section 24.1.5 Preventing Transaction ID Wraparound Failures:

“If these warnings are ignored, the system will refuse to assign new XIDs once there are fewer than three million transactions left until wraparound:”

When the oldest unfrozen XID gets dangerously close to wraparound, PostgreSQL enters a protective state that refuses new XID-assigning commands. This prevents catastrophic data loss until a VACUUM advances the frozen-xid horizon.

Common causes

  • Wraparound warnings were ignored for too long.
  • Autovacuum unable to freeze old XIDs (disabled, blocked, or starved).
  • Long-running transactions pinning the xmin horizon.

How to fix it

  1. Run VACUUM on the affected database (single-user mode if it won’t accept commands).
  2. Remove transactions/prepared-xacts/replication slots holding back the horizon.
  3. Afterwards, fix autovacuum so this never recurs.

Diagnostic query

SELECT datname, age(datfrozenxid) AS xid_age FROM pg_database ORDER BY xid_age DESC;

Track this regularly; act long before the age approaches autovacuum_freeze_max_age.

Related & next steps

Reference: PostgreSQL 18 Section 25.1 “Routine Vacuuming”.

Was this helpful?