redis/redis-py · error · SlotNotCoveredError

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

Error message

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

What it means

Raised by RedisCluster.get_node_from_key (redis/asyncio/cluster.py:845) when the key's computed slot is absent from slots_cache. The cluster client maps a key to a slot and looks up which node serves it; if topology discovery has not populated that slot (or the cluster genuinely does not cover it), it raises SlotNotCoveredError naming the slot.

Source

Thrown at redis/asyncio/cluster.py:845

    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 da03cdc7e8)

Solutions

  1. Ensure full slot coverage: run `redis-cli --cluster check` and fix missing slots.
  2. Wait for / trigger topology refresh before key-based node lookup (the client refreshes on MOVED, or call CLUSTER SLOTS explicitly).
  3. Use regular command execution (get/set) which retries on MOVED and refreshes the slot map, instead of manual get_node_from_key.
  4. Retry after a short backoff to allow discovery to populate.

Example fix

// before
node = c.get_node_from_key('mykey')  # raises if slot unknown
// after
await c.get('mykey')  # let the client refresh slots via MOVED handling
node = c.get_node_from_key('mykey')
Defensive patterns

Strategy: retry

Try / catch

from redis.exceptions import SlotNotCoveredError
for _ in range(MAX_RETRIES):
    try:
        await c.get('mykey')  # refreshes slots via MOVED handling
        node = c.get_node_from_key('mykey')
        break
    except SlotNotCoveredError:
        await asyncio.sleep(backoff)
        continue

Prevention

When it happens

Trigger: Calling get_node_from_key before initial CLUSTER SLOTS discovery completed, or against a cluster that does not cover all 16384 slots (e.g., a partially set-up or degraded cluster). slots_cache.get(slot) returns None.

Common situations: Querying a slot immediately after constructing the client (race with discovery); cluster in a mid-resharding state; cluster with fewer nodes than slots; slots_cache stale after failover until refreshed.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/0351ff9fbc646e6f.json. Report an issue: GitHub.