redis/redis-py · error · SlotNotCoveredError
Slot "{slot}" not covered by the cluster. "require_full_cove
Error message
Slot "{slot}" not covered by the cluster. "require_full_coverage={self.require_full_coverage}" What it means
A SlotNotCoveredError raised by get_node_from_slot() when slots_cache[slot] is empty/missing (IndexError) or None (TypeError). This means no node in the cached cluster topology claims responsibility for that hash slot. Whether this is fatal depends on require_full_coverage: with it True the cluster should have been rejected at startup, so this usually indicates the slot map went stale mid-run (e.g. resharding or a node drop).
Source
Thrown at redis/asyncio/cluster.py:2204
self,
slot: int,
read_from_replicas: bool = False,
load_balancing_strategy=None,
) -> "ClusterNode":
if read_from_replicas is True and load_balancing_strategy is None:
load_balancing_strategy = LoadBalancingStrategy.ROUND_ROBIN
try:
if len(self.slots_cache[slot]) > 1 and load_balancing_strategy:
# get the server index using the strategy defined in load_balancing_strategy
primary_name = self.slots_cache[slot][0].name
node_idx = self.read_load_balancer.get_server_index(
primary_name, len(self.slots_cache[slot]), load_balancing_strategy
)
return self.slots_cache[slot][node_idx]
return self.slots_cache[slot][0]
except (IndexError, TypeError):
raise SlotNotCoveredError(
f'Slot "{slot}" not covered by the cluster. '
f'"require_full_coverage={self.require_full_coverage}"'
)
def get_nodes_by_server_type(self, server_type: str) -> List["ClusterNode"]:
return [
node
for node in self.nodes_cache.values()
if node.server_type == server_type
]
async def initialize(
self,
additional_startup_nodes_info: Optional[List[Tuple[str, int]]] = None,
last_failed_node_name: Optional[str] = None,
) -> None:
self.read_load_balancer.reset()
tmp_nodes_cache: Dict[str, "ClusterNode"] = {}View on GitHub (pinned to da03cdc7e8)
Solutions
- Trigger a topology refresh and retry: await rc.reload_exception() / await rc.refresh_table_nodes() or re-create the client.
- If running with require_full_coverage=False knowingly, ensure app code avoids uncovered slots or handle SlotNotCoveredError with a refresh+retry.
- For long-lived clients, enable the cluster's topology auto-refresh so stale slots are repopulated automatically.
Example fix
// before
try:
await rc.get('user:42')
except SlotNotCoveredError:
pass
// after
try:
await rc.get('user:42')
except SlotNotCoveredError:
await rc.reload_exception()
await rc.get('user:42') Defensive patterns
Strategy: retry
Validate before calling
from redis.cluster import SlotNotCoveredError
async def get_covered(rc, key):
slot = rc.keyslot(key)
try:
node = rc.nodes_manager.get_node_from_slot(slot, rc.read_from_replicas)
except SlotNotCoveredError:
await rc.reload_exception()
node = rc.nodes_manager.get_node_from_slot(slot, rc.read_from_replicas)
return node Type guard
from redis.asyncio.cluster import RedisCluster
def slot_is_covered(rc: RedisCluster, slot: int) -> bool:
nodes = rc.nodes_manager.slots_cache.get(slot)
return bool(nodes) Try / catch
from redis.cluster import SlotNotCoveredError
for attempt in range(3):
try:
return await rc.get(key)
except SlotNotCoveredError:
await rc.reload_exception()
raise RuntimeError('slot still uncovered after topology refresh') Prevention
- Keep require_full_coverage=True (default) so the client fails fast at startup rather than mid-request.
- Wrap cluster commands in a retry helper that refreshes topology on SlotNotCoveredError.
- Avoid running clients during active resharding, or schedule a topology refresh afterwards.
When it happens
Trigger: Operating on a key whose slot is mid-reshard (moved away but not yet assigned elsewhere in the client's cache), a degraded cluster where some slots lost their owner, or require_full_coverage=False deliberately allowing partial coverage at startup and then touching an uncovered slot.
Common situations: Active resharding/rebalancing while the app runs; a node that owned slots crashed and the client's slots cache hasn't refreshed; connecting with reinitialize_steps/setuptools that allow partial coverage; slot migration tooling leaving gaps.
Related errors
- startup_nodes could not agree on a valid slots cache: {', '.
- All slots are not covered after query all startup_nodes. {le
- The requested node does not exist in the cluster.
- Slot "{slot}" is not covered by the cluster.
- Cannot execute FT.CURSOR commands without FT.AGGREGATE
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/eaed14af67536dfb.json.
Report an issue: GitHub.