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 as a RedisClusterException during topology assembly when two different nodes both claim ownership of the same slot in CLUSTER SLOTS output, and the number of such disagreements exceeds 5. The client detects the conflict at cluster.py:2755-2765 (comparing tmp_slots[i][0].name vs target_node.name) and aborts because a contradictory slots cache is unsafe to use.

Solutions

  1. Inspect the cluster with CLUSTER NODES and CLUSTER SLOTS on each node to identify which nodes disagree on slot ownership.
  2. Fix the slot assignments using CLUSTER SETSLOT / redis-cli --cluster fix to reconcile ownership.
  3. If a node is permanently divergent, remove it from the cluster (CLUSTER FORGET) and re-add it correctly.
  4. Restart the affected Redis nodes to re-sync cluster config from the persisted nodes.conf.

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

# Inspect CLUSTER SLOTS for overlapping slot ownership before connecting
import redis
standalone = redis.Redis(host, port)
slots = standalone.cluster('SLOTS')
owners = {}
for s in slots:
    for i in range(int(s[0]), int(s[1]) + 1):
        owner = s[2][2]  # node id of primary
        if i in owners and owners[i] != owner:
            print(f'Slot conflict: slot {i} claimed by {owners[i]} and {owner}')
        owners[i] = owner

Type guard

null

Try / catch

from redis.exceptions import RedisClusterException
try:
    client = RedisCluster(host, port)
except RedisClusterException as e:
    if 'could not agree' in str(e):
        # run redis-cli --cluster fix, then retry
        raise RuntimeError('Cluster has slot conflicts; run redis-cli --cluster fix') from e

Prevention

When it happens

Trigger: During initialize() / topology refresh, CLUSTER SLOTS returns slot ranges where the same slot is assigned to two different primary nodes, producing more than 5 disagreements. This indicates a corrupted or split-brain cluster topology.

Common situations: Cluster is in a split-brain state, nodes have stale slot ownership info after a botched reshard or failover, or a misconfigured cluster has overlapping slot assignments.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/819a9b6c83b37b63. Report an issue: GitHub.

Appendix: source

Thrown at redis/cluster.py:2762

                        target_replica_node = self._get_or_create_cluster_node(
                            host, port, REPLICA, tmp_nodes_cache
                        )
                        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)}"
                                    )

                fully_covered = self.check_slots_coverage(tmp_slots)
                if fully_covered:
                    # Don't need to continue to the next startup node if all
                    # slots are 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 exception

            # Create Redis connections to all nodes
            self.create_redis_connections(list(tmp_nodes_cache.values()))

View on GitHub (pinned to 6a6b581b48)