MySQL Error Guide: 'server is running with the --read-only option' — Fix Read-Only Writes
Fix MySQL error 1290 'running with the --read-only option so it cannot execute this statement': confirm you're on a replica, find stale writes, and clear read_only safely after failover.
- #mysql
- #database
- #troubleshooting
- #errors
Stuck on this MySQL error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
MySQL raises error 1290 when a write statement (INSERT, UPDATE, DELETE, or most DDL) reaches a server that has read_only or super_read_only enabled:
ERROR 1290 (HY000): The MySQL server is running with the --read-only option
so it cannot execute this statement
This is almost never a bug in MySQL — it is a guardrail doing its job. Replicas are deliberately set read-only so application writes cannot accidentally land on them and diverge from the primary. Seeing 1290 means write traffic is hitting a node that is supposed to be read-only, or a failover left the wrong node read-only.
read_only blocks writes from clients without the SUPER (or CONNECTION_ADMIN) privilege. super_read_only (MySQL 5.7.8+ and MariaDB 10.5+) closes the loophole by blocking privileged users too — which is why a script that “works as root” on the primary suddenly fails on a replica. MariaDB supports both variables identically.
Symptoms
- Reads succeed but every write fails with error 1290, always on the same node.
- The error appears immediately after a failover or maintenance switchover.
- A migration or admin script that runs fine against the primary fails when pointed at a replica or a load-balancer read endpoint.
- Writes fail even when connecting as a highly privileged user (
super_read_onlyis ON). - An ORM or connection pool intermittently throws 1290 because it routes some writes to a read replica.
Common Root Causes
- The application is writing to a replica — a misconfigured connection string, read/write split, or load balancer sending writes to a read endpoint.
- A failover or switchover did not promote the node — the intended new primary still has
read_only=ON, or the old primary was correctly demoted but traffic still points at it. - Orchestration set read_only intentionally — tools like Orchestrator, MHA, Group Replication, or a managed service (RDS/Aurora reader) enforce read-only on non-primary nodes.
- A maintenance flag left on — someone set
SET GLOBAL read_only=ONfor a controlled operation and forgot to clear it. - Group Replication single-primary mode — secondary members are automatically
super_read_onlyand cannot be written to directly. super_read_onlyblocking a privileged migration that the operator expected to bypass read-only.
Diagnostic Workflow
The first question is always “which node am I actually on, and is it the primary?” Confirm the read-only state and whether this node is a replica:
SELECT @@hostname, @@read_only, @@super_read_only;
SHOW REPLICA STATUS\G -- SHOW SLAVE STATUS\G on 5.7 / MariaDB
If SHOW REPLICA STATUS returns rows with a running I/O and SQL thread, you are on a replica and 1290 is correct behaviour — the fix is to route writes elsewhere, not to disable read-only. If it returns nothing, this node has no upstream source, so it may be an intended primary that failed to promote.
For Group Replication, check membership and primary role:
SELECT MEMBER_HOST, MEMBER_ROLE, MEMBER_STATE
FROM performance_schema.replication_group_members;
Verify who set read_only and whether it is dynamic or from config:
SHOW VARIABLES LIKE 'read_only';
SHOW VARIABLES LIKE 'super_read_only';
SHOW VARIABLES LIKE 'innodb_read_only'; -- separate, engine-level, needs restart to change
Check the error log for a recent failover or an explicit read_only change:
grep -iE 'read.?only|primary|failover|switchover' /var/log/mysql/error.log | tail
Example Root Cause Analysis
An overnight deploy started failing all INSERTs with error 1290 even though the app had run for months. On-call confirmed the connection string was unchanged.
SELECT @@hostname, @@read_only on the connected node returned the expected primary hostname but read_only = 1. SHOW REPLICA STATUS\G returned an empty set — the node had no upstream source. The error log showed an automated failover an hour earlier: Orchestrator had demoted the original primary (setting read_only=ON) and promoted a new one, but the write VIP had flapped back to the old node before it was re-promoted.
So the application was correctly reaching what it thought was the primary, but that host had been demoted to read-only and never reinstated. Blindly running SET GLOBAL read_only=OFF here would have been dangerous — it would have created a split brain with the real new primary.
The correct fix was to repoint the write VIP at the actual promoted primary (verified via the orchestration tool), leaving the demoted node read-only. Only after confirming the demoted node was not receiving replication from the new primary would it be safe to reset it.
Prevention Best Practices
- Never clear
read_onlyto “fix” 1290 without confirming the node’s role first — on a demoted primary that creates split brain and data divergence. - Enforce
super_read_only=ONon all replicas so even privileged scripts cannot accidentally write to them. - Make read/write splitting explicit — separate primary and replica connection strings (or a proxy like ProxySQL) so writes can never be routed to a reader.
- Let orchestration own read_only — the failover tool should be the single source of truth for which node is writable; avoid manual
SET GLOBAL read_onlyin production. - Add a startup guard: set
read_only=ONin the replica’s config file so a restart never comes up writable by accident. - Alert on writable replicas — a replica with
read_only=OFFis a latent split-brain risk.
Quick Command Reference
-- Am I on a writable primary or a read-only replica?
SELECT @@hostname, @@read_only, @@super_read_only;
SHOW REPLICA STATUS\G -- empty result = no upstream source
-- Group Replication role check
SELECT MEMBER_HOST, MEMBER_ROLE FROM performance_schema.replication_group_members;
-- Clear read-only ONLY after confirming this is the intended primary
SET GLOBAL super_read_only = OFF; -- must clear super_read_only first
SET GLOBAL read_only = OFF;
-- Deliberately demote a node to read-only (order matters)
SET GLOBAL super_read_only = ON; -- implicitly sets read_only = ON too
Ordering note: you cannot disable read_only while super_read_only is ON, so clear super_read_only first when promoting. Setting super_read_only=ON implicitly enables read_only. innodb_read_only is a separate, restart-only variable and is not what error 1290 refers to.
Conclusion
Error 1290 is a safety mechanism, not a failure: a write reached a node that is intentionally read-only, almost always a replica or a demoted primary. The instinct to run SET GLOBAL read_only=OFF is exactly the wrong first move — on a demoted node it manufactures split brain. Diagnose the node’s role first with SELECT @@read_only and SHOW REPLICA STATUS; if it is a genuine replica, fix the write routing, and if it is an un-promoted primary, fix the failover rather than the flag. Enforce super_read_only on readers and let your orchestration own who is writable so 1290 becomes a signal you trust instead of one you fight.
Fixed it? Get 500 MySQL & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.