How to fix 25002: branch_transaction_already_active in PostgreSQL

PostgreSQLADVANCEDHIGHUpdated Dec 22, 2025ยท 118 views

This error occurs when PostgreSQL cannot start a new transaction because one is already active in the same XA transaction branch. It commonly happens in distributed transaction scenarios with multiple resources.

Quick fix

Fixes 25002: branch_transaction_already_active

SELECT pid, usename, application_name, state, query_start, query
FROM pg_stat_activity
WHERE state = 'active'
  AND pid = pg_backend_pid();
  1. Identify active transactions on the connection
  2. Commit or rollback the existing transaction
  3. Review application transaction management code
  4. Configure max_prepared_transactions for XA support
postgresql โ€” error
SELECT pid, usename, application_name, state, query_start, query
FROM pg_stat_activity
WHERE state = 'active'
AND pid = pg_backend_pid();
25002: branch_transaction_already_active

What this error means

Error code 25002 (BRANCH_TRANSACTION_ALREADY_ACTIVE) indicates that PostgreSQL is unable to start a new transaction because one is already active in the same branch. This error is specific to XA (eXtended Architecture) transactions, which are used in distributed transaction processing across multiple databases or resources. In XA transaction management, a "branch" represents a specific transaction context within a distributed transaction. Each branch must have only one active transaction at a time. When an application or transaction manager attempts to start a new transaction on a branch that already has an active transaction, PostgreSQL throws this error to prevent transaction state corruption. This error typically occurs in Java applications using JTA/XA with application servers (like JBoss EAP, WildFly, or WebLogic), in microservices architectures with distributed transactions, or when using transaction managers like Atomikos or Narayana with PostgreSQL.

Typical symptoms

  • XA transaction operations fail with SQLSTATE 25002
  • Distributed transactions cannot be started in Java applications
  • Application server logs show "branch_transaction_already_active" errors
  • Transaction manager reports failures during transaction coordination
  • Database connections appear to be "stuck" in an active transaction state

Common causes

  1. Previous transaction on the same XA branch was not properly committed or rolled back
  2. Application code starts a new transaction before closing the previous one
  3. Transaction manager fails to properly end transactions due to network issues or timeouts
  4. Connection pooling reuses connections with dangling transactions
  5. Exception handling in application code skips transaction cleanup (COMMIT or ROLLBACK)
  6. Replication filters are configured with XA transactions (not supported)

How to fix "25002: branch_transaction_already_active"

1Identify active transactions on the connection

Query the database to see all currently active transactions:

sql
SELECT pid, usename, application_name, state, query_start, query
FROM pg_stat_activity
WHERE state = 'active'
  AND pid = pg_backend_pid();

This shows if your current connection has an active transaction that wasn't properly closed.

For all active transactions across the database:

sql
SELECT pid, now() - pg_stat_activity.query_start AS duration, query
FROM pg_stat_activity
WHERE state = 'active'
ORDER BY duration DESC;
2Commit or rollback the existing transaction

If you have control over the session, explicitly end the current transaction:

sql
-- If you want to commit the pending changes
COMMIT;

-- Or if you want to discard the changes
ROLLBACK;

After this, you should be able to start a new transaction on the same branch.

3Review application transaction management code

Check your application code for proper transaction handling. Every transaction start must have a corresponding commit or rollback:

Java/JTA example:

java
UserTransaction ut = ...;
try {
    ut.begin();
    // Your database operations
    ut.commit();
} catch (Exception e) {
    ut.rollback(); // CRITICAL: Always rollback on error
    throw e;
} finally {
    // Ensure transaction is closed
}

Common mistakes:
- Missing rollback in exception handlers
- Early returns that skip transaction cleanup
- Nested transaction attempts on the same connection

4Configure max_prepared_transactions for XA support

XA transactions require the max_prepared_transactions parameter to be set. Edit postgresql.conf:

conf
max_prepared_transactions = 100  # Should be >= max_connections

Restart PostgreSQL for changes to take effect:

bash
sudo systemctl restart postgresql

Verify the setting:

sql
SHOW max_prepared_transactions;

If this is set to 0, XA transactions cannot work properly.

5Check connection pool configuration

If using connection pooling (HikariCP, c3p0, DBCP), ensure connections are properly cleaned between uses:

HikariCP example (Java):

java
HikariConfig config = new HikariConfig();
config.setAutoCommit(true);  // Auto-commit when connection is returned
config.setConnectionTestQuery("SELECT 1");

Configure connection validation:
- Test connections before use
- Set reasonable connection timeouts
- Enable auto-commit for non-XA connections

6Terminate stuck transactions if necessary

If a transaction is stuck and cannot be closed normally, you can terminate the backend process:

sql
-- Find the process ID (pid) from pg_stat_activity
SELECT pg_terminate_backend(12345);  -- Replace with actual pid

Warning: This forcibly kills the connection and rolls back the transaction. Only use this for stuck sessions that cannot be recovered normally.

Advanced notes

XA Transaction Architecture:
XA transactions follow the two-phase commit (2PC) protocol. A transaction manager coordinates multiple resource managers (databases) through PREPARE and COMMIT phases. PostgreSQL acts as one resource manager in this distributed transaction.

Replication Limitations:
Error 25002 can occur when trying to use logical replication filters with XA transactions. PostgreSQL does not support replication filters for XA/prepared transactions. If you need both features, consider using separate connections for XA operations versus replicated data changes.

Transaction Isolation Levels:
XA transactions in PostgreSQL use the serializable isolation level by default. This can increase the likelihood of transaction conflicts in high-concurrency scenarios. Consider your isolation level requirements when designing distributed transactions.

Monitoring Prepared Transactions:
Monitor prepared transactions that haven't been committed or rolled back:

sql
SELECT gid, prepared, owner, database
FROM pg_prepared_xacts
WHERE prepared < now() - interval '1 hour';

Prepared transactions that remain for extended periods indicate transaction manager failures or application bugs that need investigation.

Connection State Management:
In pooled environments, always reset connection state when connections are returned to the pool. This includes rolling back any uncommitted transactions, resetting session variables, and clearing temporary tables.

Frequently asked questions

What does "25002: branch_transaction_already_active" mean?
Error code 25002 (BRANCH_TRANSACTION_ALREADY_ACTIVE) indicates that PostgreSQL is unable to start a new transaction because one is already active in the same branch. This error is specific to XA (eXtended Architecture) transactions, which are used in distributed transaction processing across multiple databases or resources. In XA transaction management, a "branch" represents a specific transaction context within a distributed transaction.
How do I fix "25002: branch_transaction_already_active"?
This error occurs when PostgreSQL cannot start a new transaction because one is already active in the same XA transaction branch. It commonly happens in distributed transaction scenarios with multiple resources.
What causes "25002: branch_transaction_already_active"?
Previous transaction on the same XA branch was not properly committed or rolled back Application code starts a new transaction before closing the previous one Transaction manager fails to properly end transactions due to network issues or timeouts
Is the "25002: branch_transaction_already_active" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading