Independent technical referenceOfficial site
  • Software and digital services
  • Databases

25P02

PostgreSQL 25P02 in_failed_sql_transaction: aborted block

Verified with sources3 sourcesReviewed Oct 19, 2026
Technician coming? See the 2 steps they must show you
Trace

Risk level

Medium

Proceed carefully and stop if the check is unclear.

Urgency

Medium

Quick answer

PostgreSQL returns 25P02 (in_failed_sql_transaction) because an earlier statement inside the same transaction block failed and the session has not rolled back yet. Check your logs for the first error before 25P02, then issue ROLLBACK or ROLLBACK TO a prior savepoint.

Safety first

Stop and check this first

  • Never assume the SQL statement that returned 25P02 is the broken query; 25P02 only reports that the transaction block was already aborted by a prior command.
  • Do not attempt to bypass transaction errors by disabling database constraints or triggers, and always issue ROLLBACK before starting a new unit of work on the same session.

Safe checks you can perform

  • Locate the first SQLSTATE error that preceded 25P02 on the same session
  • Check pg_stat_activity for sessions stuck in idle in transaction (aborted)
  • Review transaction state handling and SAVEPOINT usage in the client code

Leave these tasks to a qualified professional

  • Do not attempt this professional task: Fix the underlying SQL error and enforce ROLLBACK or ROLLBACK TO SAVEPOINT in code
  • Do not attempt this professional task: Verify connection pool cleanup and libpq PQTRANS_INERROR handling

What a technician must be able to justify

Technician visit

These are the steps they must carry out and show you. Tick them as they work: if steps are skipped, do not accept a part swap.

These are not instructions for opening or handling the equipment yourself. They are the checks that should support a technical conclusion.

  1. Fix the underlying SQL error and enforce ROLLBACK or ROLLBACK TO SAVEPOINT in code

    What they doHave the developer resolve the primary SQL error that triggered the abort and update the transaction error handler so it immediately issues ROLLBACK (or ROLLBACK TO a savepoint created before the optional statement) before sending any further SQL.

    They must show youthe captured first SQLSTATE before 25P02, the code diff adding ROLLBACK or SAVEPOINT / ROLLBACK TO, and integration test output.

    In writingthe root-cause SQLSTATE that preceded 25P02 and the exact transaction recovery rule implemented in the service.

  2. Verify connection pool cleanup and libpq PQTRANS_INERROR handling

    What they doHave the platform engineer or DBA verify that the connection pooler and client driver inspect transaction status (PQTRANS_INERROR in libpq) and execute ROLLBACK before returning any session to the pool.

    They must show youthe pooler check-in settings and a query against pg_stat_activity confirming zero lingering idle in transaction (aborted) sessions under load.

    In writingthe pooler reset setting and the idle_in_transaction_session_timeout value configured on the server.

Before accepting a part or repair

Nothing has been shown yet. Do not accept a part swap based on the code alone.

Follow these steps

Note: Follow the documented order. An error code identifies the affected system, but it does not prove by itself which part has failed.

  1. Locate the first SQLSTATE error that preceded 25P02 on the same session

    Tools required

    Who:
    You or your developer inspecting the application request trace or PostgreSQL server log.
    How:
    Filter the log by the backend process ID (PID), session ID, or request trace immediately before the first 25P02 entry, redacting any passwords, connection strings, or personal data before copying.
    Result that matters:
    The exact SQLSTATE code and error message of the statement that failed immediately before 25P02 began appearing.
    If an earlier statement on the same PID threw a constraint, syntax, permission, or lock error right before 25P02, that confirms the earlier statement is the true root cause to fix.
    If the very first statement of a new web request fails with 25P02 without a prior error in that request, that points to a pooled connection handed over while already in an aborted transaction block.
    Evidence to keep:
    Save the redacted log sequence showing both the initial error SQLSTATE and the subsequent 25P02 message on the same PID.

    Never ignore the initial error or suppress 25P02 in logs; always redact sensitive query literals before sharing log excerpts.

    Evidence: PostgreSQL 18 Appendix A: Error Codes · PostgreSQL 18 libpq connection status functions · PostgreSQL 18 transactions tutorial

  2. Check pg_stat_activity for sessions stuck in idle in transaction (aborted)

    Tools required

    Who:
    Your DBA or developer with read access to pg_stat_activity.
    How:
    Run a read-only SELECT on pg_stat_activity filtering for state = 'idle in transaction (aborted)' to inspect pid, usename, application_name, xact_start, state_change, and query.
    Result that matters:
    Whether client backends are lingering in the aborted transaction state instead of rolling back promptly.
    If pg_stat_activity lists backends in state idle in transaction (aborted) for that application_name, that confirms client sessions are failing to issue ROLLBACK after query errors.
    If no backends remain in idle in transaction (aborted), that indicates the application eventually rolls back at request end after emitting one or more 25P02 errors mid-request.
    Evidence to keep:
    Record the pid, application_name, xact_start, state_change, and redacted query text from pg_stat_activity.

    Do not attempt to fix aborted transactions by killing server processes at the OS level; use only read-only catalog queries during diagnosis.

    Evidence: PostgreSQL ROLLBACK · PostgreSQL 18 cumulative statistics system

  3. Review transaction state handling and SAVEPOINT usage in the client code

    No special tools

    Who:
    Your developer examining the data-access layer or ORM transaction block.
    How:
    Check whether the code expects to recover from an expected error inside a transaction block using SAVEPOINT and ROLLBACK TO, or whether it should abort the whole block with ROLLBACK.
    Result that matters:
    Whether every catch block inside a BEGIN ... COMMIT scope issues either ROLLBACK or ROLLBACK TO a valid savepoint defined before the failed command.
    If a catch block swallows an exception inside a transaction without calling ROLLBACK TO a prior savepoint, that confirms why PostgreSQL rejects the next query with 25P02.
    If the driver checks PQtransactionStatus and resets connections reporting PQTRANS_INERROR via ROLLBACK before reuse, that rules out pool state leakage.
    Evidence to keep:
    Keep the file and line numbers of the catch block and the connection pool reset configuration.

    Evidence: PostgreSQL ROLLBACK · PostgreSQL 18 libpq connection status functions · PostgreSQL 18 transactions tutorial

Still not solved

If the error persists, stop here. See what the technician must do and show you.

Virtual technician

Does 25P02 still appear after these checks?

This guided flow uses the exact code and your answers to choose a test, an expected result and the next branch.

Where this code applies

A code is meaningful only inside the right product and version context.

Primary scope

System
Software and digital services
Brand
PostgreSQL
Product type
Databases

Known code variants

  • in_failed_sql_transaction
  • PostgreSQL 25P02
  • SQLSTATE 25P02

What it means

Appendix A lists 25P02 as in_failed_sql_transaction in Class 25, Invalid Transaction State. Once any SQL command errors inside a BEGIN ... COMMIT transaction block, PostgreSQL places that transaction block into an aborted state (reported by libpq as PQTRANS_INERROR and in pg_stat_activity as idle in transaction (aborted)) and rejects further commands until the session executes ROLLBACK or rolls back to a SAVEPOINT created before the failure. Code 25P02 is a follow-on symptom of an unhandled earlier error and never proves by itself that the statement currently returning 25P02 is invalid or that the database server is damaged.

Warnings and stop conditions

  • Mediumsource verified

    Never assume the SQL statement that returned 25P02 is the broken query; 25P02 only reports that the transaction block was already aborted by a prior command.

    Evidence: PostgreSQL 18 Appendix A: Error Codes · PostgreSQL 18 transactions tutorial

  • Highsource verified

    Do not attempt to bypass transaction errors by disabling database constraints or triggers, and always issue ROLLBACK before starting a new unit of work on the same session.

    Evidence: PostgreSQL ROLLBACK · PostgreSQL 18 transactions tutorial

Symptoms and causes

Probable causes · in order

  • Application continuing to send SQL commands after catching or ignoring an earlier errorConfirmed

    When a query inside a transaction block fails and the client code catches the exception without issuing ROLLBACK or ROLLBACK TO SAVEPOINT, the next statement sent on that transaction receives 25P02.

    Evidence: PostgreSQL 18 Appendix A: Error Codes · PostgreSQL ROLLBACK · PostgreSQL 18 transactions tutorial

  • Client driver or ORM opening implicit transaction blocks without automatic rollbackCommon

    Some client libraries and connection wrappers issue BEGIN automatically, so a single failed query leaves the session in PQTRANS_INERROR state across subsequent calls on the same connection.

    Evidence: PostgreSQL 18 libpq connection status functions · PostgreSQL 18 transactions tutorial

  • Connection pool returning a session left in idle in transaction (aborted) statePossible

    If a pooled connection is returned to the pool after a statement error without executing ROLLBACK, the next borrower inherits the aborted transaction block and immediately hits 25P02.

    Evidence: PostgreSQL ROLLBACK · PostgreSQL 18 libpq connection status functions · PostgreSQL 18 cumulative statistics system

Sources and technical references

  1. 1

    PostgreSQL 18 Appendix A: Error Codes

    PostgreSQL Global Development Group · 2026 · official_doc

  2. 2

    PostgreSQL transaction isolation

    PostgreSQL Global Development Group · 2026 · official_doc

  3. 3

    PostgreSQL ROLLBACK

    PostgreSQL Global Development Group · 2026 · official_doc

Sources: PostgreSQL 18 Appendix A: Error Codes · PostgreSQL transaction isolation · PostgreSQL ROLLBACKreviewed 2026-10-19 · verified

Was this entry useful?