Redis READONLY You can’t write against a read only replica - causes and fixes
Your application hits (error) READONLY You can't write against a read only replica. Writes fail; reads work. The connected Redis instance thinks it is a replica, so it rejects mutating commands. The replica is behaving correctly. The problem is a write-capable client routed to a node that is not the current primary. This typically happens in three situations: a routing bug that sends writes to a replica endpoint, stale client topology after a failover or upgrade, or an instance that was accidentally demoted at runtime.
What this means
Replicas operate in read-only mode by default via the replica-read-only yes directive (called slave-read-only before Redis 5). When a client issues a write command such as SET, DEL, or LPUSH to a replica, Redis returns the READONLY error to prevent dataset divergence from the primary. The mode can be toggled at runtime with CONFIG SET replica-read-only yes|no, and it is automatically enforced when an instance becomes a replica via REPLICAOF host port. The error signals a topology mismatch: the client expects a master, but the server reports role:slave.
Common causes
| Cause | What it looks like | First thing to check |
|---|---|---|
| Routing bug or hardcoded replica endpoint | Writes fail consistently from specific clients; reads against the same node succeed | INFO replication role and slave_read_only on the target node |
| Stale topology after failover, upgrade, or restart | Errors spike immediately after a failover event; some application instances work while others do not | Client connection target and Sentinel or load balancer state |
Runtime reconfiguration (REPLICAOF, accidental demotion) | All writes to the node fail after maintenance or an operator command; the node should be a master | INFO replication role and CONFIG GET replica-read-only |
| Client read preference routing write commands to replicas | Intermittent READONLY during normal operations; often affects Lua scripts or transactions routed to replicas | Client library read-routing configuration |
Quick checks
# Confirm instance role and read-only state
redis-cli INFO replication | grep -E "role|slave_read_only"
# Check runtime read-only configuration
redis-cli CONFIG GET replica-read-only
# Check if error replies are climbing
redis-cli INFO stats | grep total_error_replies
# Check replication link and offset lag on a replica
redis-cli INFO replication | grep -E "master_link_status|master_repl_offset|slave_repl_offset"
# Examine connected clients and their origin
redis-cli CLIENT LIST | head -20
# If using Sentinel, verify which node is currently master
redis-cli -p 26379 SENTINEL MASTER mymaster
How to diagnose it
flowchart TD
A[Client issues write] --> B{INFO replication role}
B -->|master| C[Write accepted]
B -->|slave| D[READONLY error]
D --> E{Should this node be master?}
E -->|Yes| F[Check: failover, Sentinel, CONFIG drift]
E -->|No| G[Fix: route writes to actual master]
F --> H[Verify master_repl_offset across nodes]
F --> I[Check client topology refresh]
F --> J[Audit CONFIG SET / REPLICAOF history]- Confirm the node’s role. Run
INFO replicationon the instance returning the error. Ifrole:slaveandslave_read_only:1, the node is correctly behaving as a read-only replica. - Verify whether this node should be a master. Compare against your deployment topology. If it should be a master, it has been demoted.
- Check for recent failover or restart events. Look at
uptime_in_secondsfor unexpected resets, review Sentinel logs, or check your cloud provider’s maintenance event history. - Inspect client routing configuration. Check application connection strings, DNS records, and load balancer targets for hardcoded replica IPs or stale primary endpoints.
- Look for runtime reconfiguration. Run
INFO commandstatsand scan forcmdstat_replicaoforcmdstat_configincreases. Check Redis server logs for recentCONFIG SETcommands. - Audit client library topology state. For Lettuce, Spring Data Redis, go-redis, or ioredis, check whether connections were established before failover completed and whether topology refresh is enabled. Verify that write commands are not being sent with replica-preferring read settings.
- Measure replication offset lag. If you have multiple candidates for primary, compare
master_repl_offsetacross nodes to identify which one is actually leading.
Metrics and signals to monitor
| Signal | Why it matters | Warning sign |
|---|---|---|
role in INFO replication | Detects unexpected demotion from master to replica | role:slave on a node expected to be master |
slave_read_only | Confirms read-only mode is active | Value of 1 on a node receiving write attempts |
total_error_replies rate | Captures write rejections and other errors | Sustained increase after topology changes |
master_repl_offset vs slave_repl_offset | Quantifies replication lag and identifies the true primary | Offset not increasing on the node clients treat as master |
sync_full and sync_partial_err | Indicates replicas are falling behind and requiring full resyncs | Spikes after failovers or network blips |
cmdstat_replicaof / cmdstat_config | Detects runtime topology changes via commands | Non-zero counts outside maintenance windows |
Fixes
Route writes to the current primary
If the node is legitimately a replica, redirect write-capable clients to the current primary. Update connection strings, service discovery records, or load balancer targets. Do not hardcode individual node endpoints in HA deployments. On AWS ElastiCache, use the primary endpoint rather than node endpoints.
Refresh stale client topology
When client libraries cache topology across failover:
- Restart application instances that hold stale connections to the old primary.
- Reduce topology refresh intervals in client configuration during planned maintenance.
- For Lettuce-based clients, validate that writes use master routing and that replica preferences are reserved for confirmed read-only operations.
Promote the replica back to primary
If the node was incorrectly demoted:
- Run
REPLICAOF NO ONEto make it an independent master. Warning: Only do this if you are certain no other master is active for the same dataset. Creating a split-brain will diverge data. - If Sentinel manages the topology, prefer Sentinel-driven failover instead of manual promotion.
Temporarily allow writes on the replica
In emergencies, run CONFIG SET replica-read-only no. Warning: This causes the replica to accept writes and diverge from its primary. Use only as a temporary measure, and rebuild the replica afterwards.
Rebuild the replica
If the replica diverged or you enabled temporary writes:
- Run
REPLICAOF NO ONEto clear the existing replication link if necessary. - Run
REPLICAOF correct_primary_host portto reattach. - Allow a full resync to complete. Monitor
master_link_statusand offset lag until the replica is caught up.
Prevention
- Use primary and reader endpoints rather than individual node IPs. In Kubernetes, ensure the service or operator endpoint targets the current master.
- Configure client libraries with topology refresh so they detect failovers faster than application-level connection timeouts.
- Monitor
roleandslave_read_onlyon every node that should accept writes. - Restrict
CONFIGandREPLICAOFcommands using ACLs orrename-commandto prevent accidental or unauthorized demotion. - Set
min-replicas-to-writeandmin-replicas-max-lagto prevent the primary from accepting writes when replicas are disconnected or severely lagging.
How Netdata helps
- Charts
INFO replicationrole transitions alongsidetotal_error_repliesspikes, so you can pinpoint when a demotion causes write failures. - Tracks replication offset lag and
master_link_statusper node to verify a promoted replica is healthy before routing writes. - Surfaces
uptime_in_secondsresets next to connection spikes to distinguish cold-start topology issues from persistent routing bugs. - Highlights
commandstatsforreplicaofandconfigexecutions that precede unexpected READONLY errors. - Monitors
connected_clientson former primaries after failover to detect applications still sending traffic to the old node.
Related guides
- How Redis actually works in production: a mental model for operators
- Redis aof_last_write_status:err: AOF write failures and recovery
- Redis appendfsync always latency: durability vs throughput trade-offs
- Redis BUSY Redis is busy running a script: blocking Lua and how to recover
- Redis Can’t save in background: fork: Cannot allocate memory - diagnosis and fix
- Redis client output buffer overflow: slow consumers and client-output-buffer-limit
- Redis connected_clients climbing: connection leak detection
- Redis connection exhaustion: leaks, pools, and the retry storm
- Redis event loop blocked: when one slow command freezes everything
- Redis eviction policy tuning: allkeys-lru vs volatile-ttl vs noeviction
- Redis fork/COW memory storm: why persistence doubles RSS and OOM-kills the box
- Redis KEYS command blocking production: why to replace it with SCAN







