MySQL ERROR 1290: –read-only option so it cannot execute this statement
A write that fails with ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement is a routing or topology problem, not a query problem. The server refuses the statement because read_only or super_read_only is enabled. You are likely sending writes to a replica, a recently promoted primary that never cleared its read-only flag, or a node correctly enforcing super_read_only. Confirm the instance role and fix the write path.
What this means
read_only rejects write statements from ordinary client connections. Users with the SUPER privilege can still write. super_read_only is stricter: it also blocks SUPER users and forces read_only on. Clearing read_only forces super_read_only off. Replicas typically run with read_only to prevent accidental divergence. When an application receives ERROR 1290, the server is enforcing its configured role. The root cause is almost always infrastructure around MySQL: a stale load balancer rule, a failover script that did not promote the new primary, or a connection pool sending writes to the wrong host.
flowchart TD
A[Write fails with ERROR 1290] --> B{Check read_only and super_read_only}
B -->|Both OFF| C[Investigate proxy or app routing]
B -->|read_only ON| D{Is this a replica?}
D -->|Yes| E[Fix client routing to primary]
D -->|No| F{super_read_only ON?}
F -->|Yes| G[Clear stale flag after failover]
F -->|No| H[Check for global read lock]Common causes
| Cause | What it looks like | First thing to check |
|---|---|---|
| Write routed to a replica | All writes from specific app hosts fail with ERROR 1290; reads work fine | SHOW GLOBAL VARIABLES LIKE 'read_only'; on the target |
| Stale topology after failover | Writes failed immediately after a failover; the promoted node rejects them | SHOW GLOBAL VARIABLES LIKE 'super_read_only'; |
| Read/write split or proxy misconfiguration | Intermittent ERROR 1290 under load; some connections succeed | Proxy backend rules and health-check logic |
| Operator maintenance on a replica | A script or command fails on a host that was assumed to be primary | SHOW REPLICA STATUS\G to confirm replication role |
Quick checks
Run these safe, read-only commands to orient yourself.
-- Check read-only state
SHOW GLOBAL VARIABLES WHERE Variable_name IN ('read_only', 'super_read_only');
-- Confirm if this is a replica
SHOW REPLICA STATUS\G
-- On MySQL 5.7 and earlier: SHOW SLAVE STATUS\G
-- Check current user privileges
SHOW GRANTS FOR CURRENT_USER();
-- Check Group Replication membership
SELECT MEMBER_ID, MEMBER_HOST, MEMBER_PORT, MEMBER_STATE
FROM performance_schema.replication_group_members;
-- Check for long-running transactions that may block state changes
SELECT trx_mysql_thread_id, trx_started, trx_query
FROM information_schema.INNODB_TRX
ORDER BY trx_started ASC;
-- Check processlist for maintenance locks
SHOW PROCESSLIST;
# Check error log for recent role changes. Path varies by system.
grep -i "read_only\|group_replication" /var/log/mysql/error.log | tail -20
How to diagnose it
- Locate
ERROR 1290in application logs. Confirm the error code and the message referencing the read-only option. - Run
SHOW GLOBAL VARIABLESforread_onlyandsuper_read_onlyon the target instance. If both areOFF, the error is coming from a different server than you expect. Trace the connection through your proxy or load balancer. - Determine if the instance is a replica. Run
SHOW REPLICA STATUS\G. IfReplica_IO_RunningandReplica_SQL_Runningare bothYes, this is an active replica and should not receive writes. - If the instance is not a replica but
super_read_onlyisON, check whether it was recently promoted after a failover. Promotion scripts must explicitly runSET GLOBAL super_read_only=OFFon the new primary. If they did not, the instance remains read-only. - If the instance belongs to a Group Replication cluster, query
performance_schema.replication_group_members. A node that showsMEMBER_STATE = ONLINEbut hassuper_read_only = ONis a secondary. Do not disablesuper_read_onlyon it. - If you are trying to disable
read_onlyorsuper_read_onlyand the statement hangs or fails, check for long-running transactions ininformation_schema.INNODB_TRXandSHOW PROCESSLISTfor explicit locks or maintenance operations blocking state changes. - If the instance is correctly read-only, the fix is entirely on the client side. Verify application connection strings, proxy routing rules, and DNS entries that direct writes to this host.
Metrics and signals to monitor
| Signal | Why it matters | Warning sign |
|---|---|---|
read_only and super_read_only | Identifies whether the instance rejects writes | Either is ON on a node expected to be primary |
| Replication thread state | Distinguishes replicas from standalone or primary nodes | Replica_IO_Running and Replica_SQL_Running both Yes |
| Group Replication member state | Flags secondaries that enforce super_read_only | MEMBER_STATE is ONLINE but super_read_only is enabled |
Seconds_Behind_Source | Reveals stale replicas that may be misrouted | Lag growing beyond application tolerance |
Threads_connected / max_connections | Reveals connection storms from retry loops | Ratio spiking after ERROR 1290 onset |
Fixes
Replica receiving writes
The database is correctly configured. Redirect writes to the primary. Update your load balancer, proxy, or application connection pool so write traffic targets the writable node. Verify with a test write from the appropriate endpoint. If you are using a managed service, connect to the read/write endpoint rather than a read-only replica endpoint.
Stale super_read_only after failover
If this node was promoted to primary but still has super_read_only = ON, disable it. This requires SUPER or SYSTEM_VARIABLES_ADMIN.
SET GLOBAL super_read_only=OFF;
Warning: This makes the node writable. If you run this on a node that is still a replica, you will create a split-brain scenario.
If the command hangs, there may be an active global read lock or long-running transaction blocking the change. Check SHOW PROCESSLIST for maintenance locks and information_schema.INNODB_TRX for old transactions. Kill the blocker only if you have confirmed it is safe to do so, then retry.
Group Replication secondary
Do not manually disable super_read_only on a secondary to force writes. Group Replication manages this flag; a secondary with super_read_only = ON is not the primary. Route writes to the current primary, which the group maintains as writable. If the group has no primary, initiate failover with your Group Replication runbook.
Maintenance scripts failing on replicas
If an operator or backup tool must run maintenance on a replica, remember that super_read_only blocks even SUPER users. You must either run the maintenance on the primary or temporarily disable super_read_only on the replica. Disabling it introduces a window where accidental writes can occur, so do this only during a maintenance window and re-enable it immediately after.
Prevention
- Automate failover scripts to clear
super_read_onlyon promotion and set it on demotion. Include verification steps that issue a test write before marking the node as primary in your load balancer. - Monitor
read_onlyandsuper_read_onlyon every node expected to accept writes. Alert immediately if either is enabled on a primary endpoint. - Tag load balancer backends with their role (primary vs replica) and validate that health checks distinguish writable from read-only nodes. A simple
SELECT @@read_onlyas a health check can prevent routing mistakes. - After any topology change, run a smoke test that executes a controlled write to confirm the endpoint is truly writable before directing production traffic to it.
- Reserve one administrative connection outside your application pool for emergency diagnosis. If
max_connectionsis reached and the node is read-only by mistake, you need a privileged path in to fix it. This only helps when the node runs withread_onlyalone, becausesuper_read_onlyblocks all users.
How Netdata helps
- Netdata collects MySQL global variables including
read_onlyandsuper_read_only, so you can alert when a production primary unexpectedly becomes read-only. - Netdata monitors replication thread state and
Seconds_Behind_Source, distinguishing replicas from primaries in real time. - Netdata tracks
Threads_connectedandAborted_connects, exposing connection storms that follow routing misconfiguration. - Netdata’s MySQL error log integration can correlate
ERROR 1290frequency with topology changes or failover events.
Related guides
- How MySQL actually works in production: a mental model for operators
- MySQL Aborted_connects and Aborted_clients climbing: diagnosis
- MySQL adaptive hash index latch contention: high CPU, low throughput
- MySQL InnoDB buffer pool hit ratio collapse: the cliff edge
- MySQL slow after restart: buffer pool warm-up and the cold cache
- MySQL innodb_buffer_pool_size tuning: 60-80% of RAM and when that breaks
- MySQL Innodb_buffer_pool_wait_free > 0: buffer pool memory pressure
- MySQL InnoDB checkpoint age: the redo log capacity signal nobody watches
- MySQL connection exhaustion: detection, diagnosis, and prevention
- MySQL innodb_deadlock_detect=OFF: when deadlock detection becomes the bottleneck
- MySQL ERROR 1213: Deadlock found when trying to get lock; try restarting transaction
- MySQL FLUSH TABLES WITH READ LOCK stall: backups that freeze the server







