# XX001 — data_corrupted

> Source-backed full reference for PostgreSQL SQLSTATE XX001.
---

# XX001

## At a glance {#at-a-glance}

`XX001` reports an integrity invariant failure. The fixed sources cover corrupted PGLZ TOAST data, impossible MultiXact/XID freeze state in heap processing, and an `amcheck` B-tree check that can reveal a heap/HOT-chain problem behind an apparent index mismatch.

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| Field | Value |
| --- | --- |
| SQLSTATE | `XX001` |
| Condition | `data_corrupted` |
| Status | `active` |
| Known present by | `7.4` |
| Locked snapshots | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| Macros | `ERRCODE_DATA_CORRUPTED` |
| Aliases | `—` |

<!-- source facts: data/errcodes/XX001.json -->
<!-- END SQLSTATE FACTS -->

## Meaning {#meaning}

The TOAST decompressor raises `ERRCODE_DATA_CORRUPTED` when PGLZ cannot decode the stored compressed datum. Heap freezing raises the same code when a MultiXact precedes `relminmxid`, remains running before the freeze cutoff, or carries an update XID before `relfrozenxid` or the removable cutoff. These are consistency checks on stored data and transaction metadata, not invalid user input.

The `amcheck` `heapallindexed` callback reports a heap tuple lacking its matching index tuple. Its source comments warn that an apparent index-scan problem can still be heap corruption, a bad HOT-safety decision, or another underlying fault; the optional hint only asks for a stronger verification call.

## Messages {#messages}

- **ERROR**, SQLSTATE `XX001`: `compressed pglz data is corrupt`.
- **ERROR**, SQLSTATE `XX001`: `found multixact %u from before relminmxid %u`.
- **ERROR**, SQLSTATE `XX001`: `multixact %u from before multi freeze cutoff %u found to be still running`.
- **ERROR**, SQLSTATE `XX001`: `multixact %u contains update XID %u from before relfrozenxid %u`.
- **ERROR**, SQLSTATE `XX001`: `multixact %u contains committed update XID %u from before removable cutoff %u`.
- **ERROR**, SQLSTATE `XX001`: `heap tuple (%u,%u) from table "%s" lacks matching index tuple within index "%s"`.
  - When the check was entered through `bt_index_check` (which takes `AccessShareLock` and passes `readonly=false` to the callback), hint: `Retrying verification using the function bt_index_parent_check() might provide a more specific error.` The `bt_index_parent_check` entry point takes `ShareLock`, passes `readonly=true`, and does not append this hint. This internal verification mode is unrelated to the SQL transaction's `transaction_read_only` setting.

## Diagnosis {#diagnosis}

Preserve the exact message and identifiers, relation/index names, block and page context, checksum and replica comparison, server log, and the first operation that observed the invariant. For TOAST, identify the owning table and compressed datum path. For heap messages, inspect relfrozenxid/relminmxid and MultiXact history without manually editing system catalogs. For `amcheck`, record whether the call used `bt_index_check`/`AccessShareLock` or `bt_index_parent_check`/`ShareLock`, and whether the hint was present; do not assume the index is the root cause.

## Response {#response}

Treat these as integrity incidents. In an explicit transaction, an `ERROR` requires `ROLLBACK` or `ROLLBACK TO` an existing savepoint before more SQL, but rollback does not repair the stored object. Compare trusted backups, replicas, checksums and storage history using a read-only procedure; then restore or rebuild the affected table/TOAST data according to the incident plan. A REINDEX may be appropriate only after evidence shows corruption is index-local; it is not a generic repair for heap, TOAST, XID, or MultiXact invariants. If a separate FATAL or process termination occurred, use a new connection after recovery; do not induce corruption to test this code.

## Versions {#versions}

The locked catalogue records this condition from 7.4; fixed TOAST, heap, and amcheck source coverage is PostgreSQL 18.6. No corruption or crash runtime was run for this source-only page.

## Related {#related}

[`XX002`](../xx002/), [`58030`](../58030/), [`72000`](../72000/)

## Sources {#sources}

[`src/backend/access/common/toast_compression.c#L90-L100`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/access/common/toast_compression.c#L90)

[`src/backend/access/heap/heapam.c#L6983-L7042`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/access/heap/heapam.c#L6983)

[`contrib/amcheck/verify_nbtree.c#L2760-L2818`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/contrib/amcheck/verify_nbtree.c#L2760)

[`contrib/amcheck/verify_nbtree.c#L252-L305`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/contrib/amcheck/verify_nbtree.c#L252)

[`contrib/amcheck/verify_common.c#L60-L149`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/contrib/amcheck/verify_common.c#L60)

The structured [evidence record](../data/evidence/xx001.json) records the integrity message groups, conditional hint, and source/runtime boundary.
