# 25004 — inappropriate_isolation_level_for_branch_transaction

> PostgreSQL SQLSTATE 25004: the branch-transaction isolation-level condition, with a fixed source boundary.
---

# 25004 — inappropriate_isolation_level_for_branch_transaction

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

`25004` names an inappropriate isolation level for a branch transaction. The fixed PostgreSQL 18.6 resolved-call scan has no direct report group for this code, so no ordinary SQL reproduction is claimed.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `25004` |
| Condition | `inappropriate_isolation_level_for_branch_transaction` |
| 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_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION` |
| Aliases | `—` |

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

## Meaning {#meaning}

This is a branch-transaction condition, separate from `40001` serialization failure and from the normal `SET TRANSACTION ISOLATION LEVEL` checks documented for an ordinary transaction.

## Diagnosis {#diagnosis}

Keep the branch API, requested isolation level, and transaction state together when diagnosing it. The source evidence does not justify borrowing a message from another isolation-level error.

## Response {#response}

Correct the isolation-level negotiation in the branch API, then retry only if that API defines retry semantics. An ordinary SQL session should be diagnosed with the SQLSTATE it actually returned.

## Source message and runtime boundary {#messages}

The fixed `errcodes.txt` row defines the condition and macro; the resolved call scan in `raw/calls/REL_18_6.jsonl` contains no direct report group, so this batch publishes no message template and constructs no natural SQL trigger.

## Applicability boundary and case {#case}

The selected runner cases on PostgreSQL 18.6 and 10.21 are `not_applicable`; they record the source boundary and contain no copyable SQL trigger. [Structured evidence](../data/evidence/25004.json) · [case export](../data/cases/25004.json)

## Versions and limits {#versions}

The generated facts record the locked catalogue snapshots. Both runner targets are source-boundary observations with `not_applicable` case status; no natural trigger is being promoted to runtime coverage.

## Related {#related}

[25003 branch transaction access mode](../25003/), [40001 serialization failure](../40001/), [25P01 no active SQL transaction](../25p01/).

## 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` — `raw/calls/REL_18_6.jsonl` (SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf`)
