redis/redis-py · critical · RedisClusterException
startup_nodes could not agree on a valid slots cache: {', '.
Error message
startup_nodes could not agree on a valid slots cache: {', '.join(disagreements)} What it means
Raised during initialize() when more than 5 slot-ownership disagreements accumulate across startup nodes. As the client merges CLUSTER SLOTS replies from multiple nodes, if two different nodes claim ownership of the same slot (line 2350 check), the disagreement is recorded; exceeding the threshold aborts bootstrapping because the topology is inconsistent and cannot be safely resolved.
Source
Thrown at redis/asyncio/cluster.py:2356
)
# add this node to the nodes cache
tmp_nodes_cache[target_replica_node.name] = target_replica_node
nodes_for_slot.append(target_replica_node)
for i in range(int(slot[0]), int(slot[1]) + 1):
if i not in tmp_slots:
tmp_slots[i] = nodes_for_slot
else:
# Validate that 2 nodes want to use the same slot cache
# setup
tmp_slot = tmp_slots[i][0]
if tmp_slot.name != target_node.name:
disagreements.append(
f"{tmp_slot.name} vs {target_node.name} on slot: {i}"
)
if len(disagreements) > 5:
raise RedisClusterException(
f"startup_nodes could not agree on a valid "
f"slots cache: {', '.join(disagreements)}"
)
# Validate if all slots are covered or if we should try next startup node
fully_covered = True
for i in range(REDIS_CLUSTER_HASH_SLOTS):
if i not in tmp_slots:
fully_covered = False
break
if fully_covered:
break
if not startup_nodes_reachable:
raise RedisClusterException(
f"Redis Cluster cannot be connected. Please provide at least "
f"one reachable node: {str(exception)}"
) from exceptionView on GitHub (pinned to da03cdc7e8)
Solutions
- Retry client creation after resharding/failover completes (await asyncio.sleep then reconstruct RedisCluster).
- Reduce startup_nodes to a single known-good seed node so only one CLUSTER SLOTS view is trusted.
- Ensure the cluster is healthy (CLUSTER NODES shows no fail/pfail state) before the client connects.
Example fix
// before rc = RedisCluster(startup_nodes=[nodeA, nodeB, nodeC]) # during reshard // after # wait for reshard to finish, then seed from one node rc = RedisCluster(host='seed-host', port=6379)
Defensive patterns
Strategy: retry
Validate before calling
import asyncio
from redis.asyncio.cluster import RedisCluster
async def connect_stable(startup_nodes, max_retries=3):
for attempt in range(max_retries):
try:
return await RedisCluster(startup_nodes=startup_nodes)
except Exception as e:
if 'could not agree' in str(e):
await asyncio.sleep(2 ** attempt)
continue
raise
raise RuntimeError('cluster topology still unstable') Type guard
def cluster_looks_healthy(cluster_nodes_text: str) -> bool:
lines = [l for l in cluster_nodes_text.splitlines() if l and not l.startswith('node')]
return all('fail' not in l.split()[-2].lower() for l in lines if len(l.split()) >= 8) Try / catch
from redis.cluster import RedisClusterException
try:
rc = RedisCluster(startup_nodes=seeds)
except RedisClusterException as e:
if 'could not agree' in str(e):
# wait for reshard/failover to settle and seed from one node
await asyncio.sleep(5)
rc = RedisCluster(host=seeds[0].host, port=seeds[0].port)
else:
raise Prevention
- Avoid constructing the client during active resharding or failover.
- Seed from a single known-good node rather than many divergent seeds.
- Verify cluster_state:ok via CLUSTER INFO before connecting.
When it happens
Trigger: Bootstrapping against a cluster mid-reshard where slots are being migrated and nodes disagree transiently; connecting during an unstable split-brain; nodes running mismatched cluster configs; a partially-failed failover leaving conflicting slot claims.
Common situations: Connecting during active slot migration/rebalancing; a flaky network partition where nodes' CLUSTER SLOTS are out of sync; multiple startup_nodes pointing at different sub-clusters.
Related errors
- Slot "{slot}" not covered by the cluster. "require_full_cove
- Cluster mode is not enabled on this node
- Redis Cluster cannot be connected. Please provide at least o
- All slots are not covered after query all startup_nodes. {le
- The requested node does not exist in the cluster.
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/2f35cc87756dfb37.json.
Report an issue: GitHub.