Diagnostic Queries
Symptoms
SET TRANSACTION ISOLATION LEVEL was issued after the transaction had already executed a query. The isolation level can only be set at the very start of a transaction, so PostgreSQL raises SQLSTATE 25001 (active_sql_transaction).
- Happens when the SET arrives after the first statement.
- Common in pooled connections that already ran a query.
- The isolation level must be the first action in the transaction.
What the server log shows
ERROR: SET TRANSACTION ISOLATION LEVEL must be called before any query
Why PostgreSQL raises this — what the manual says
As the SET TRANSACTION reference (Notes) explains:
SET TRANSACTION must be issued before the transaction’s first query or data-modification statement; once a statement has run, the isolation level and access mode for that transaction are fixed and can no longer be changed.
The isolation level fixes the transaction snapshot behaviour from its first statement onward. Changing it after work has begun would be ambiguous, so PostgreSQL rejects a late SET with 25001.
Common causes
- Setting the isolation level after running a query in the same transaction.
- A pooler handing back a connection that already issued statements.
- ORM code that issues SELECTs before configuring isolation.
How to fix it
- Set the isolation level as the first statement after
BEGIN. - Use
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;to set it atomically. - Set
default_transaction_isolationif every transaction needs the same level.
Related & next steps
Reference: PostgreSQL 18 — SET TRANSACTION.
Thanks — noted. This helps keep the database accurate.