# 25000 — invalid_transaction_state

> PostgreSQL SQLSTATE 25000: the broad invalid_transaction_state condition and its internal parallel-operation boundary.
---

# 25000 — invalid_transaction_state

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

`25000` is the broad Class 25 invalid transaction state. The locked 18.6 source uses it for internal states such as executing a utility or defining a savepoint during a parallel operation. This batch does not claim a safe ordinary SQL reproduction.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `25000` |
| Condition | `invalid_transaction_state` |
| 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_INVALID_TRANSACTION_STATE` |
| Aliases | `—` |

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

## Meaning {#meaning}

Transaction state is more specific than “a transaction exists”. The same class contains `25001` for active transaction restrictions and `25P02` for a failed transaction. The resolved 18.6 call scan shows `25000` guards in heap access, transaction, utility, GUC, and savepoint paths that depend on parallel-worker state.

## Diagnosis {#diagnosis}

First distinguish a failed transaction (`25P02`), an active transaction block restriction (`25001`), and a parallel-operation state (`25000`). For a natural client error, preserve the exact source SQLSTATE and message; do not infer `25000` from a generic “transaction is open” observation.

## Response {#response}

Follow the command’s documented transaction and parallel-worker contract. If the server reports a recoverable client transaction state, use the exact rollback or retry boundary; if it is an internal parallel-operation guard, collect server logs and context before changing application SQL. Do not manufacture a natural result with `RAISE`.

## Source message templates {#messages}

- `parallel-savepoint`: primary `cannot define savepoints during a parallel operation` (ERROR).
- `parallel-utility`: primary `cannot execute %s during a parallel operation` (ERROR).

## Applicability boundary {#case}

This batch does not construct a natural SQL trigger for `25000`; treat it as a source/protocol boundary rather than a copyable reproduction. [structured evidence](../data/evidence/25000.json) · [case export](../data/cases/25000.json).

Authored evidence IDs: `identity`, `core-paths`, `boundary`. Selected runtime records: —.

## Versions {#versions}

The locked catalogue observes the condition by `7.4` and in all listed formal snapshots. The 18.6 source scan confirms the cited parallel-operation paths; this page intentionally has no runtime case because the required internal state is not a safe standalone SQL precondition.

## Related {#related}

Compare [25001 active SQL transaction](../25001/), [25P02 failed SQL transaction](../25p02/), and [40001 serialization failure](../40001/).

## Sources {#sources}

- [`src.errcodes.18.6`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt) (SHA-256 `6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba`)
- `src.calls.REL_18_6` (SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf`)
- [`src.xact.18.6`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/access/transam/xact.c#L4385-L4387) (SHA-256 `75b012c0b047d1dc905a30975c244beec366e45eac0dbf109fd21bcd611a8e39`)
- [`src.utility.18.6`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/utility.c#L425-L429) (SHA-256 `7aae5d07628b6debf8456d1d4ea96f28912232192e56ea25773b4c4b61235a00`)
