PostgreSQL error 25006 occurs when your session attempts to write to the database while in read-only mode. Read-only mode can be enabled at the database, session, or transaction level, preventing any INSERT, UPDATE, DELETE, or DDL operations. Disable read-only mode or connect to the primary server to resolve this.
Error 25006 indicates that PostgreSQL is enforcing read-only mode to protect data integrity. When a transaction is read-only, the database rejects any attempt to modify data or schema. This happens because either the database-wide setting default_transaction_read_only is enabled, your session has read-only mode set, or you're connected to a read-only replica/standby instance. Read-only mode is commonly used for hot standby replicas, disaster recovery scenarios, or to protect databases during maintenance. The error prevents unintended data modifications in protected environments.
Connect to PostgreSQL as a superuser and run:
SHOW default_transaction_read_only;If it returns "on", your database is in read-only mode. You can also check session-level settings:
SELECT * FROM pg_database WHERE datname = current_database();If the setting is ON, disable it for your database:
ALTER DATABASE your_database SET default_transaction_read_only = off;Replace your_database with your actual database name. This change takes effect for new connections. For immediate effect in your current session, also run:
SET default_transaction_read_only = off;Disconnect and reconnect to verify the change took effect:
SHOW default_transaction_read_only;It should now return "off". Try your write operation again.
If you're using PostgreSQL replication, verify you're connecting to the primary (read-write) server, not a standby:
SELECT pg_is_in_recovery();If this returns true, you're on a standby. Update your connection string to point to the primary server instead.
If you need to execute writes immediately and can't change the database setting, you can override it for your current session:
SET default_transaction_read_only = off;This affects only your current connection and will reset when you disconnect. For ORMs, check if there's a way to configure this at connection initialization.
If using Heroku, Railway, AWS RDS, or similar services:
1. Log into your service dashboard
2. Check if your database is undergoing maintenance
3. Wait for maintenance to complete (usually 5-30 minutes)
4. Try your operation again
Upgrading to a production/standard tier usually eliminates these temporary read-only windows.
Read-only mode is legitimate for standby replicas in replication setups. If you have a multi-node PostgreSQL cluster, never attempt to write to standby servers. Instead, use cascade replication or connection poolers like pgBouncer to automatically route writes to the primary.
For applications, implement connection retry logic with exponential backoff to handle temporary read-only states during maintenance. Some frameworks (e.g., Rails, Django) have built-in support for this.
You can also create deferrable read-only transactions that wait for a safe point to execute:
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE;
-- Your SELECT queries here
COMMIT;For PostgreSQL 13+, you can force terminate other connections when dropping a database:
DROP DATABASE database_name WITH (FORCE);ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL