Fix 'DENY COMMANDS ASKING WRITE. REPLICA can't execute write commands.' in Redis

intermediate๐Ÿ”ด Redis2026-03-21| Redis 2.6+, Redis Cluster, Redis Sentinel, any OS (Linux/macOS/Windows)

Error Message

(error) DENY COMMANDS ASKING WRITE. REPLICA can't execute write commands.
#redis#replication#replica#write

TL;DR

You sent a write command (SET, DEL, INCR, etc.) to a Redis replica node. Replicas are read-only by default โ€” they don't accept writes. Connect to the master node instead. Or, if you have a specific reason, temporarily allow writes on the replica with CONFIG SET replica-read-only no.

Why This Error Happens

Redis replication flows one way: master โ†’ replica(s). The replica continuously syncs data from the master and rejects every write command with:

(error) DENY COMMANDS ASKING WRITE. REPLICA can't execute write commands.

A few situations that trip people up:

  • You hardcoded a replica's IP/port in your app config and forgot to update it after a failover.
  • Redis Sentinel promoted a new master, but your client is still pointing at the old one โ€” now a replica.
  • You connected to the wrong port. In a typical two-node setup, 6379 is the master and 6380 is the replica, but this varies.
  • Your connection pool round-robins across nodes without knowing which one is the master.

Check Which Node You're On

Run ROLE via redis-cli to see the node's role immediately:

redis-cli -h <host> -p <port> ROLE

A replica responds like this:

1) "slave"
2) "192.168.1.10"
3) (integer) 6379
4) "connected"
5) (integer) 12345

A master responds like this:

1) "master"
2) (integer) 12345
3) 1) 1) "192.168.1.11"
      2) "6379"
      3) "12345"

See slave in the output? You're on the wrong node for writes.

Fix 1: Connect to the Master Node (Recommended)

Run ROLE on each node to find the master, or use INFO replication:

redis-cli -h <host> -p <port> INFO replication

Find the line role:master. That host and port is where all writes should go.

Redis Sentinel Setup

Skip hardcoded IPs entirely. Ask Sentinel which node is currently the master:

redis-cli -h <sentinel-host> -p 26379 SENTINEL get-master-addr-by-name mymaster

This returns the current master's IP and port โ€” even after a failover. Better yet, use a Sentinel-aware client so your app never needs to ask manually:

# Python (redis-py)
from redis.sentinel import Sentinel

sentinel = Sentinel(
    [('sentinel-host', 26379)],
    socket_timeout=0.1
)
master = sentinel.master_for('mymaster', socket_timeout=0.1)
master.set('key', 'value')  # Always routes to the current master

Redis Cluster Setup

Cluster-aware clients handle slot-to-master routing automatically. No manual node selection needed:

# Python (redis-py cluster)
from redis.cluster import RedisCluster

rc = RedisCluster(host='node1', port=6379, decode_responses=True)
rc.set('key', 'value')  # Client figures out which shard master owns this key

Fix 2: Allow Writes on a Replica (Testing Only)

Sometimes you genuinely need to write to a replica โ€” say, during local testing or a one-off migration step. Disable read-only mode at runtime:

redis-cli -h <replica-host> -p <port> CONFIG SET replica-read-only no

On Redis older than 5.0, the config key was named differently:

redis-cli -h <replica-host> -p <port> CONFIG SET slave-read-only no

Warning: Anything you write directly to a replica gets wiped the next time the master syncs. This causes data divergence. Never use this in production without a solid plan.

To make the change survive a restart, edit redis.conf on the replica:

replica-read-only no

Then restart Redis:

sudo systemctl restart redis

Fix 3: After a Failover โ€” Update Your App Config

Sentinel or Cluster triggered a failover. Your app is still hardcoded to the old master's address โ€” which is now a replica. Update the config:

# Before failover (stale โ€” now pointing at a replica)
REDIS_HOST=192.168.1.10
REDIS_PORT=6379

# After failover (correct โ€” the new master)
REDIS_HOST=192.168.1.11
REDIS_PORT=6379

That fixes it short-term. For the long run, switch to a Sentinel or Cluster client. Your app will handle future failovers on its own, no config edits required.

Verify the Fix

Pointed at the master? Run a quick write/read/delete cycle to confirm:

redis-cli -h <master-host> -p 6379 SET testkey "hello"
# Expected: OK

redis-cli -h <master-host> -p 6379 GET testkey
# Expected: "hello"

redis-cli -h <master-host> -p 6379 DEL testkey
# Expected: (integer) 1

Also check that replication itself is healthy:

redis-cli -h <master-host> -p 6379 INFO replication | grep -E 'role|connected_slaves|slave'

You want to see role:master and at least one connected slave in the output.

Quick Reference: Which Setup Are You Using?

  • Standalone replica: Run ROLE on each node to find the master, then connect directly to it.
  • Redis Sentinel: Use SENTINEL get-master-addr-by-name, or better โ€” a Sentinel-aware client library.
  • Redis Cluster: Use a cluster-aware client. It routes writes to the correct shard master automatically.

Related Error Notes