PostgreSQL raises error 25006 read_only_sql_transaction when a write statement runs inside a transaction that has been marked read only.
PostgreSQL error 25006 read_only_sql_transaction appears when a session issues INSERT, UPDATE, DELETE, or DDL while the current transaction is read only. End the transaction or start a new one without the READ ONLY flag, or connect to a writable primary instead of a read replica.
PostgreSQL Error 25006 read_only_sql_transaction
Error 25006 fires when PostgreSQL detects an attempt to modify data within a transaction that is declared READ ONLY. The server blocks the operation to protect data consistency on read replicas or in explicitly read only sessions.
The error stops any INSERT, UPDATE, DELETE, or DDL statement until the transaction ends or is restarted in read write mode.
Fixing it quickly is critical because no changes will persist while the transaction remains read only.
The most common trigger is connecting to a hot standby or logical read replica that forbids writes by default. Applications that fail over to a replica unknowingly run into 25006 on their first write.
The error also occurs when a client executes SET TRANSACTION READ ONLY or runs inside a function that called SET LOCAL default_transaction_read_only = on.
Superuser maintenance scripts can accidentally inherit this mode.
First, confirm whether the session is on a replica or on the primary. If on a replica, reconnect to the primary node for write activity. If on the primary, commit or roll back the current read only transaction and start a fresh one without the READ ONLY clause.
If your code sets default_transaction_read_only, change it to READ WRITE or remove the directive.
In ORMs, disable automatic read only transactions for write paths.
Cloud read replicas like AWS RDS or GCP AlloyDB reject writes. Switch the connection string to the writer endpoint to clear the error.
During maintenance, administrators sometimes SET default_transaction_read_only = on to prevent writes. Remember to reset it afterward with SET ... = off.
Background jobs that wrap logic in BEGIN READ ONLY inadvertently prevent later write statements.
Split read and write logic into separate transactions to avoid the clash.
Always label replica connection strings clearly and configure your pooler to route writes only to the primary. Monitor pg_stat_activity to catch write attempts on replicas in real time.
Inside Galaxy, you can tag connections as read only or read write.
The editor warns when an INSERT or DDL targets a read only handle, helping developers correct the mistake before execution.
Error 25007 cannot_deferrable_sql_transaction arises from DEFERRABLE misuse in the same transaction-state class. Error 25001 active_sql_transaction appears when SET commands require no active transaction. The fixes involve ending the incorrect transaction state before issuing the statement.
.
No. You must end the read only transaction and start a new one in READ WRITE mode because PostgreSQL applies the flag to the entire transaction block.
No data is lost. PostgreSQL halts the write before execution, so existing rows remain unchanged.
Many production setups use read replicas for scaling reads. Local development usually connects directly to a writable primary, masking the issue.
Galaxy lets you label connections as read replica or primary. The IDE highlights potentially unsafe writes against read replicas and suggests switching to a writable connection.