This error means your Redis client tried to execute a write command on a replica that’s configured to only accept reads, and the replica correctly refused.
The most common reason is that your application isn’t aware of which Redis instance is the master and which are replicas, and it’s sending write commands to the wrong place. This can happen if your connection pool or client library isn’t configured to route writes to the master.
Cause 1: Application logic sending writes to replicas.
- Diagnosis: Connect to your replica instance using
redis-cli -h <replica_host> -p <replica_port>. Then runINFO replication. Look forrole:slave. If it’srole:slave, your client is talking to a replica. Try running a simple write command likeSET testkey testvalue. You should get(error) READONLY You can't write against a read only replica.. - Fix: Reconfigure your application’s Redis client or connection pool to ensure write commands (
SET,DEL,HSET,LPUSH, etc.) are always directed to the master instance. If you’re using a sentinel setup, ensure your client is configured to use Redis Sentinel to discover the master. - Why it works: Redis replication is unidirectional. Replicas are passive mirrors of the master’s data; any writes must originate from the master and then be propagated.
Cause 2: Redis Sentinel misconfiguration or failure.
- Diagnosis: If you’re using Redis Sentinel for high availability, check the Sentinel logs (
/var/log/redis/sentinel.logor similar). Look for errors related to failing to connect to the master or quorum issues. Runredis-cli -p <sentinel_port> SENTINEL mastersandredis-cli -p <sentinel_port> SENTINEL replicas <master_name>to see Sentinel’s view of your topology. Ensure the master is marked ass_down_time:0andmaster-failover-state:ok. - Fix: Ensure your Sentinel instances have a quorum (e.g.,
sentinel quorum <master_name> 2) that allows them to agree on a master failure. Restart any Sentinel processes that are stuck or unresponsive. Verify that Sentinel can reach all Redis instances. - Why it works: Sentinel’s primary job is to monitor the master and orchestrate failovers. If it incorrectly believes the master is down or cannot reach it, it might not correctly inform clients where to send writes.
Cause 3: Replica’s replica-read-only configuration.
- Diagnosis: Connect to your replica instance with
redis-cli -h <replica_host> -p <replica_port>. RunCONFIG GET replica-read-only. If the output is1, it’s enforcing read-only mode. - Fix: Edit your
redis.conffile on the replica and setreplica-read-only no. Then, restart the Redis server process for that replica. - Why it works: This directive explicitly controls whether a replica will accept write commands. Setting it to
noallows writes, though this is generally discouraged for standard replication setups as it can lead to data divergence.
Cause 4: Master-replica replication lag.
- Diagnosis: On your master, run
redis-cli INFO replication. Note themaster_repl_offset. On your replica, runredis-cli INFO replication. Note theslave_repl_offset. Calculate the difference:master_repl_offset - slave_repl_offset. A large, consistently growing difference indicates significant lag. - Fix: Ensure sufficient network bandwidth between your master and replicas. Check for network latency or packet loss. If the master is overloaded, optimize its performance (e.g., reduce RDB save frequency, tune
maxmemory). If the replica is overloaded, scale its resources. - Why it works: While this doesn’t directly cause the
READONLYerror (the replica should refuse writes regardless of lag), severe lag can sometimes be a symptom of underlying network or resource issues that might also affect how quickly Sentinel detects master failures, indirectly impacting failover and client redirection. More importantly, if you did temporarily allow writes on a replica (Cause 3), this lag means data might be stale.
Cause 5: READONLY command manually executed on replica.
- Diagnosis: Connect to the replica instance (
redis-cli -h <replica_host> -p <replica_port>). RunLASTSAVE. If the save time is very old orLASTSAVEreturns0, the replica might have been started in a state where it hasn’t yet synced from the master, or it was manually reset. Check the replica’sredis.conffor anyslaveofdirectives. - Fix: If the replica was intended to be a read-only replica, ensure it is properly configured to replicate from the master. If the
slaveofdirective is missing or incorrect inredis.conf, add/correct it and restart the replica. If the replica was manually put into read-only mode with theREADONLYcommand, this state is not persistent across restarts. A restart of the replica will clear theREADONLYstate. - Why it works: The
READONLYcommand is a client-side command that can be sent to any Redis instance to enforce read-only mode for the current connection. While it’s not typically used in production for enforcing read-only for all clients, if it was run, that specific connection will be blocked from writing. This state is connection-specific and lost on disconnect.
Cause 6: Connection pooling and stale connections.
- Diagnosis: If your application uses a connection pool, a connection might have been established when the instance was the master, but then the instance was demoted (or a failover occurred) and it became a replica. The pool might still be returning this "stale" connection for writes. Check your connection pool’s configuration for settings related to connection validation or re-establishment after topology changes.
- Fix: Configure your connection pool to validate connections before use or to automatically re-establish connections if they become invalid. Many client libraries have specific mechanisms for dynamic discovery of the master in a Sentinel setup.
- Why it works: Connection pools aim for performance by reusing connections. If the pool doesn’t detect that the underlying instance’s role has changed, it will continue to send write commands to an instance that is no longer the master.
The next error you’ll likely encounter, after ensuring writes go to the master, is a MOVED error if your client isn’t correctly handling cluster redirections or if you’re not using Sentinel and have a stale master IP.