redis/redis-py · error · SlotNotCoveredError

Slot " " is not covered by the cluster.

Error message

Slot "{slot}" is not covered by the cluster.

What it means

Raised by get_node_from_key when the computed key_slot has no entry in the slots cache — i.e. no node is known to own that hash slot. SlotNotCoveredError subclasses RedisClusterException. Typically a symptom that topology discovery has not run, is stale, or the cluster genuinely has uncovered slots (require_full_coverage=False).

Solutions

  1. Trigger discovery first: run any cluster command (e.g. await client.cluster_nodes()) or call client.get_nodes() before get_node_from_key.
  2. If slots can legitimately be uncovered, handle SlotNotCoveredError and retry after a refresh.
  3. Ensure require_full_coverage=True (default) for clusters that should cover all 16384 slots.

Example fix

// before
node = client.get_node_from_key('user:42')
// after
await client.cluster_nodes()  # ensure topology is populated
node = client.get_node_from_key('user:42')
Defensive patterns

Strategy: validation

Validate before calling

await client.cluster_nodes()  # force topology discovery
slot = client.keyslot(key)
if client.nodes_manager.slots_cache.get(slot) is None:
    raise ValueError(f'slot {slot} for key {key!r} not covered')
node = client.get_node_from_key(key)

Type guard

def slot_is_covered(client, key) -> bool:
    return client.nodes_manager.slots_cache.get(client.keyslot(key)) is not None

Try / catch

from redis.exceptions import SlotNotCoveredError
for _ in range(max_attempts):
    try:
        node = client.get_node_from_key(key)
        break
    except SlotNotCoveredError:
        await client.cluster_nodes()  # refresh topology
else:
    raise

Prevention

When it happens

Trigger: Calling get_node_from_key(key) before the initial CLUSTER NODES/SLOTS discovery populated slots_cache; calling it right after construction without any command having triggered discovery; a cluster with require_full_coverage=False where some slots have no owner.

Common situations: Using get_node_from_key for manual routing without first issuing a command that triggers topology refresh; cluster still forming/scaling; slots_cache evicted after a failed rediscovery.

Related errors


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

Appendix: source

Thrown at redis/asyncio/cluster.py:846

    def get_node_from_key(
        self, key: str, replica: bool = False
    ) -> Optional["ClusterNode"]:
        """
        Get the cluster node corresponding to the provided key.

        :param key:
        :param replica:
            | Indicates if a replica should be returned
            |
              None will returned if no replica holds this key

        :raises SlotNotCoveredError: if the key is not covered by any slot.
        """
        slot = self.keyslot(key)
        slot_cache = self.nodes_manager.slots_cache.get(slot)
        if not slot_cache:
            raise SlotNotCoveredError(f'Slot "{slot}" is not covered by the cluster.')

        if replica:
            if len(self.nodes_manager.slots_cache[slot]) < 2:
                return None
            node_idx = 1
        else:
            node_idx = 0

        return slot_cache[node_idx]

    def get_random_primary_or_all_nodes(self, command_name):
        """
        Returns random primary or all nodes depends on READONLY mode.
        """
        if self.read_from_replicas and command_name in READ_COMMANDS:
            return self.get_random_node()

        return self.get_random_primary_node()

View on GitHub (pinned to 6a6b581b48)