Redis MOVED redirect — Fix Cluster Slot Routing Errors
Diagnose Redis cluster MOVED errors by checking slot ownership, node announcements, and client topology refresh, then configure a cluster-aware client correctly.
Symptoms
- MOVED 3999 10.0.0.12:6379 is returned instead of the value
- Some keys work and others fail after adding or resharding nodes
- Errors cluster around a failover, scale-out event, or DNS change
- The client reconnects to the same node and receives MOVED again
Possible causes
- The client connects with a standalone driver that does not follow cluster redirects
- The client cached a stale slot map after a failover or resharding
- Nodes advertise unreachable private IPs because cluster-announce-ip is wrong
- A NAT or load balancer hides node addresses, so redirects point somewhere the client cannot reach
Diagnosis steps
Reproduce the redirect with a cluster-aware CLI
redis-cli -c -h 10.0.0.10 -p 6379 get user:42Interpretation
With -c the CLI follows MOVED and prints the value; without it you see the raw redirect. If -c works, the cluster is healthy and the application client is the problem.
Check slot coverage and cluster state
redis-cli -h 10.0.0.10 -p 6379 CLUSTER INFO && redis-cli -h 10.0.0.10 -p 6379 CLUSTER SLOTSInterpretation
cluster_state must be ok and cluster_slots_assigned must be 16384. CLUSTER SLOTS lists which node owns each range and the address clients are told to use.
Inspect what each node announces
redis-cli -h 10.0.0.10 -p 6379 CLUSTER NODES | awk '{print $2, $3, $8}'Interpretation
The address column must be reachable from the application network. Docker or NAT environments often announce container IPs that only work inside the host.
Run the cluster consistency check
redis-cli --cluster check 10.0.0.10:6379Interpretation
The report shows slot ownership, open slots, and any node that disagrees about the configuration. It also prints the exact address used for redirects.
Root cause
Redis Cluster shards the keyspace across 16384 slots. Any node can compute the slot for a key but only the owning master serves it, so a non-owner replies with MOVED and the address of the correct node. A standalone client treats MOVED as a value or error, and a cluster client with a stale topology keeps asking the old owner. Wrong announce addresses or hidden NAT make the redirect target unusable.
Fix
Use a cluster-aware client with topology refresh enabled, seed it with several reachable nodes, and make sure cluster-announce-ip and cluster-announce-port advertise addresses the application can reach. After resharding, let the client refresh slots or restart the pool. Do not put a plain TCP load balancer in front of cluster nodes unless it is cluster-aware.
Risk note
Manually flushing the client slot cache or restarting nodes during resharding can cause transient MOVED and TRYAGAIN errors. Changing announce addresses requires a rolling restart and can briefly split the cluster view. Never enable cluster-require-full-coverage casually on a degraded cluster.
Verify the fix
Run redis-cli --cluster check and confirm every slot has an owner and all nodes agree. Then execute reads and writes for keys in several slots through the application and verify no MOVED or CLUSTERDOWN errors appear during a rolling failover test.
MOVED is a routing instruction
A MOVED reply is not a data error. The node that received the command computed the key’s hash slot, found that another master owns it, and told the client where to go:
(error) MOVED 3999 10.0.0.12:6379
A standalone Redis client does not follow that instruction. A cluster-aware client does, but only if its cached slot map is current and the advertised address is reachable.
Prove the cluster is healthy
Start with the CLI in cluster mode, which follows redirects automatically:
redis-cli -c -h 10.0.0.10 -p 6379 get user:42
redis-cli -h 10.0.0.10 -p 6379 CLUSTER INFO
redis-cli --cluster check 10.0.0.10:6379
cluster_state:ok and cluster_slots_assigned:16384 mean the cluster itself is serving all slots. CLUSTER SLOTS then shows the address each node advertises, which is often the source of trouble in Docker, Kubernetes, or NAT deployments.
Fix the topology the client sees
Set cluster-announce-ip and cluster-announce-port on every node to an address reachable from the application network, not the container-internal one. Configure the driver with multiple seed nodes and a short topology refresh interval, and verify the driver actually supports cluster mode; many “Redis cache” wrappers silently use a standalone connection.
MOVED 3999 10.0.0.12:6379
-> client refreshes slots, reconnects to 10.0.0.12, retries once
Do not point a generic TCP load balancer at a single cluster node and expect it to route slots. If you need a proxy, use one that understands cluster topology.
Verify across slots
Write keys that hash to different slots, then force a failover with CLUSTER FAILOVER on a replica. The application should see a brief retry and then continue; sustained MOVED or CLUSTERDOWN means the client is not refreshing topology or the announced address is still wrong. Confirm with redis-cli --cluster check that no slots are open and all nodes share the same view.