EADONLY database replication_error ai_generated true

redis.exceptions.ReadOnlyError: READONLY You can't write against a read only replica.

ID: database/redis-readonly

Also available as: JSON · Markdown
89%Fix Rate
91%Confidence
48Evidence
2023-01-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
7 active

Root Cause

A write command was sent to a Redis replica (slave) node which is read-only by default. This happens when the application connects to a replica instead of the primary, often after a failover event changes which node is primary, or when using Redis Sentinel/Cluster without proper client configuration.

generic

Workarounds

  1. 92% success Use Redis Sentinel-aware client to automatically discover the current primary
    Configure your Redis client to use Sentinel discovery. Python example: from redis.sentinel import Sentinel; sentinel = Sentinel([('sentinel-host', 26379)]); master = sentinel.master_for('mymaster'); master.set('key', 'value'). The client will automatically follow failovers.
  2. 85% success Manually promote the replica to primary if the original primary is lost
    On the replica, run: REPLICAOF NO ONE. This promotes it to an independent primary that accepts writes. Then reconfigure other replicas to follow the new primary: REPLICAOF new-primary-host 6379. Update application connection strings.

Dead Ends

Common approaches that don't work:

  1. Setting replica-read-only no on the replica to allow writes 90% fail

    Allowing writes on a replica breaks replication consistency. Writes to the replica are not replicated to the primary or other replicas, and will be overwritten on the next sync. This creates data divergence and silent data loss.

  2. Hardcoding the primary Redis host IP in the application 75% fail

    After a failover, the primary role moves to a different node. A hardcoded IP will point to the old primary (now a replica). The application needs to discover the current primary dynamically.

Error Chain

Leads to:
Preceded by:
Frequently confused with: