25P02
Read PG 18 manual ↗in_failed_sql_transaction
- SQLSTATE
- 25P02
- Condition name
- in_failed_sql_transaction
- Class
- Invalid Transaction State
- Source macro
- ERRCODE_IN_FAILED_SQL_TRANSACTION
- Evidence
- Observed at runtime in the source evidence
English SQLSTATE atlas: authored explanations and source/runtime evidence are separate from the manual definitions. View source ↗
At a glance
25P02 is usually the second diagnostic, not the root cause. In the selected case a duplicate key first returns 23505; a following SELECT is rejected with 25P02 while the block remains INERROR. ROLLBACK is required before a valid retry.
Meaning
postgres.c checks the aborted transaction state before planning another ordinary command and reports current transaction is aborted, commands ignored until end of transaction block. A driver exposes the corresponding failed transaction status; the original error remains the diagnostic anchor, while 25P02 tells the client that ordinary work is no longer admissible in this block.
Diagnosis
Locate the first statement error before acting on 25P02, and log both diagnostics with the connection transaction status. The selected runs show root 23505, then 25P02, INERROR after each, IDLE after ROLLBACK, and a committed valid row after a new explicit BEGIN/COMMIT. Check whether a savepoint was established before the root error: ROLLBACK TO SAVEPOINT can preserve the outer transaction, whereas without one the whole failed block must end. A pool must not hand an INERROR connection to another request.
Response
Stop issuing business statements after the first error. Preserve the root SQLSTATE and details. If a deliberately established savepoint is still usable, roll back to it and continue the outer transaction; otherwise issue ROLLBACK, verify the connection is IDLE, and start a fresh transaction. Re-evaluate the operation instead of blindly replaying the root statement.
Source message
The fixed primary message is current transaction is aborted, commands ignored until end of transaction block. It describes the state left by an earlier error and does not replace the root SQLSTATE, DETAIL, or constraint identity.
Observed diagnostics
18.6 (Homebrew) / latest: root SQLSTATE 23505; secondary SQLSTATE 25P02; after root/secondary INERROR; after rollback IDLE; rows [[1, 'seed'], [2, 'repaired']].
10.21 (Debian 10.21-1.pgdg90+1) / pg10: root SQLSTATE 23505; secondary SQLSTATE 25P02; after root/secondary INERROR; after rollback IDLE; rows [[1, 'seed'], [2, 'repaired']].
Representative case
The runner reads the root error, secondary diagnostic, rollback, and valid retry statements below from the shared registry; complete assertions, environment, and cleanup are in case export.
-- create
CREATE TABLE items(id integer PRIMARY KEY, note text UNIQUE NOT NULL);
-- seed
INSERT INTO items VALUES (1, 'seed');
-- begin
BEGIN;
-- trigger
INSERT INTO items VALUES (2, 'seed');
-- followup
SELECT 1 AS ignored;
-- rollback
ROLLBACK;
-- repair_begin
BEGIN;
-- repair
INSERT INTO items VALUES (2, 'repaired');
-- commit
COMMIT;
-- verify
SELECT id, note FROM items ORDER BY id;
The SQLSTATE, diagnostics, states, and repair assertions for this excerpt come from the shared registry (SHA-256 04da3240dcf3c03fe60d13715f8187350fadf5b8d1f10e5b837acd45289759cd); structured evidence.
Authored evidence IDs: identity, abort-state, runtime. Selected runtime records: runtime.25P02-batch2-latest-20260909.latest, runtime.25P02-batch2-pg10-20260909.pg10.
Versions and limits
The selected duplicate-key-to-25P02 case passes on PostgreSQL 18.6 and 10.21. It demonstrates transaction-state recovery, not a claim that the duplicate itself can be retried unchanged.
Sources
src.errcodes.18.6(SHA-2566e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)src.calls.REL_18_6—raw/calls/REL_18_6.jsonl(SHA-2569ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)src.postgres.18.6(SHA-2569fb62275b1badf94d01ab351337b60410cd9b3ab1fe63fa9f23d6d2185a21061)doc.libpq.18.6(SHA-256a91ce8f29dde162245d2f35f839e8b7192f62a57e01020b80564af65edd09440) · official documentation
Source evidence
Evidence belongs to the frozen source and runtime versions listed here. It is not a runtime verification of the selected manual version.
25P02 is in_failed_sql_transaction in Class 25.
Method: Read the fixed condition row and macro.
Limits: It describes the transaction state after a prior error; it is often a secondary diagnostic.
After an error aborts a transaction block, postgres.c rejects subsequent commands with 25P02 until COMMIT/ROLLBACK ends the block.
Method: Trace IsAbortedTransactionBlockState and the libpq PQTRANS_INERROR state.
Limits: The first error remains the root cause; 25P02 tells the client to stop issuing ordinary work and end the transaction.
The selected case first raises 23505, then observes 25P02 while INERROR, rolls back to IDLE, and commits a valid row in a new explicit transaction on both targets.
Method: Read the selected summaries and structured diagnostics.
Limits: The repair demonstrates transaction-state recovery; it does not make the original duplicate valid.
runtime runtime.25P02-batch2-latest-20260909.latest runtime.25P02-batch2-pg10-20260909.pg10
- src/backend/utils/errcodes.txt · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 raw/calls/REL_18_6.jsonl· ·- src/backend/tcop/postgres.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - doc/src/sgml/libpq.sgml · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7
Message templates
ERROR · aborted
Primary
current transaction is aborted, commands ignored until end of transaction block
The message is secondary to the earlier statement error; errdetail_abort may add context.
Reproduction & repair cases
failed_transaction_recovery · PG 10, 18
Preconditions
- A runner-owned disposable target is provisioned.
Trigger: Raise a root unique violation, then issue a query before ROLLBACK.
Expected assertions
- The root duplicate is 23505
- The follow-up command reports 25P02
- The failed transaction remains INERROR until ROLLBACK
- A new explicit transaction commits the repaired row
Repair: Follow the explicit transaction or source boundary described by the case.
Cleanup: Drop the case schema with an owner connection.
Recorded runtime evidence
18.6 (Homebrew) · passed
Run: 25P02-batch2-latest-20260909
{
"primary": "current transaction is aborted, commands ignored until end of transaction block",
"sqlstate": "25P02",
"after_25P02": "INERROR",
"final_status": "IDLE",
"root_primary": "duplicate key value violates unique constraint \"items_note_key\"",
"root_sqlstate": "23505",
"after_rollback": "IDLE",
"after_root_error": "INERROR",
"rows_after_retry": [
[
1,
"seed"
],
[
2,
"repaired"
]
]
}10.21 (Debian 10.21-1.pgdg90+1) · passed
Run: 25P02-batch2-pg10-20260909
{
"primary": "current transaction is aborted, commands ignored until end of transaction block",
"sqlstate": "25P02",
"after_25P02": "INERROR",
"final_status": "IDLE",
"root_primary": "duplicate key value violates unique constraint \"items_note_key\"",
"root_sqlstate": "23505",
"after_rollback": "IDLE",
"after_root_error": "INERROR",
"rows_after_retry": [
[
1,
"seed"
],
[
2,
"repaired"
]
]
}Definition snapshot: english-manuals:63d7bf92a3bee9e3998d5bba5f1… · English manual source