# 25002 — branch_transaction_already_active

> PostgreSQL SQLSTATE 25002: the narrow branch_transaction_already_active definition.
---

# 25002 — branch_transaction_already_active

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

`25002` names a branch transaction that is already active. It is narrower than `25001` and separate from `25P02`; this page records the locked condition definition and the absence of a resolved core 18.6 call site.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `25002` |
| Condition | `branch_transaction_already_active` |
| 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_BRANCH_TRANSACTION_ALREADY_ACTIVE` |
| Aliases | `—` |

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

## Meaning {#meaning}

The code belongs to Class 25, but it should not be used as a generic label for nested transactions or savepoints. PostgreSQL’s core `errcodes.txt` defines the macro, while the exhaustive resolved 18.6 call scan in this project contains no direct `25002` report group.

## Diagnosis {#diagnosis}

Use the exact server SQLSTATE and transaction context. Distinguish a branch/transaction-management API from ordinary savepoints, subtransactions, active transaction-block restrictions, and failed-transaction recovery. A missing core report group is not permission to infer a message or trigger from another code.

## Response {#response}

Preserve the branch-management operation and its transaction boundary, then consult the API that created the branch. This batch does not provide a natural SQL repair because no safe core path was confirmed; do not replace the missing path with a hand-written `RAISE` example.

## Source message templates {#messages}


## Applicability boundary {#case}

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

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

## Versions {#versions}

The locked catalogue observes the condition by `7.4` and in all listed formal snapshots. The 18.6 call scan has no resolved core path; extensions or future code may add one.

## Related {#related}

Compare [25001 active SQL transaction](../25001/), [25000 invalid transaction state](../25000/), and [3B000 savepoint exception](../3b000/).

## 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`)
