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

CauseWhat it looks likeFirst thing to check
Write routed to a replicaAll writes from specific app hosts fail with ERROR 1290; reads work fineSHOW GLOBAL VARIABLES LIKE 'read_only'; on the target
Stale topology after failoverWrites failed immediately after a failover; the promoted node rejects themSHOW GLOBAL VARIABLES LIKE 'super_read_only';
Read/write split or proxy misconfigurationIntermittent ERROR 1290 under load; some connections succeedProxy backend rules and health-check logic
Operator maintenance on a replicaA script or command fails on a host that was assumed to be primarySHOW 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

  1. Locate ERROR 1290 in application logs. Confirm the error code and the message referencing the read-only option.
  2. Run SHOW GLOBAL VARIABLES for read_only and super_read_only on the target instance. If both are OFF, the error is coming from a different server than you expect. Trace the connection through your proxy or load balancer.
  3. Determine if the instance is a replica. Run SHOW REPLICA STATUS\G. If Replica_IO_Running and Replica_SQL_Running are both Yes, this is an active replica and should not receive writes.
  4. If the instance is not a replica but super_read_only is ON, check whether it was recently promoted after a failover. Promotion scripts must explicitly run SET GLOBAL super_read_only=OFF on the new primary. If they did not, the instance remains read-only.
  5. If the instance belongs to a Group Replication cluster, query performance_schema.replication_group_members. A node that shows MEMBER_STATE = ONLINE but has super_read_only = ON is a secondary. Do not disable super_read_only on it.
  6. If you are trying to disable read_only or super_read_only and the statement hangs or fails, check for long-running transactions in information_schema.INNODB_TRX and SHOW PROCESSLIST for explicit locks or maintenance operations blocking state changes.
  7. 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

SignalWhy it mattersWarning sign
read_only and super_read_onlyIdentifies whether the instance rejects writesEither is ON on a node expected to be primary
Replication thread stateDistinguishes replicas from standalone or primary nodesReplica_IO_Running and Replica_SQL_Running both Yes
Group Replication member stateFlags secondaries that enforce super_read_onlyMEMBER_STATE is ONLINE but super_read_only is enabled
Seconds_Behind_SourceReveals stale replicas that may be misroutedLag growing beyond application tolerance
Threads_connected / max_connectionsReveals connection storms from retry loopsRatio 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_only on 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_only and super_read_only on 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_only as 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_connections is 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 with read_only alone, because super_read_only blocks all users.

How Netdata helps

  • Netdata collects MySQL global variables including read_only and super_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_connected and Aborted_connects, exposing connection storms that follow routing misconfiguration.
  • Netdata’s MySQL error log integration can correlate ERROR 1290 frequency with topology changes or failover events.