redis/redis-py · critical · RedisClusterException
All slots are not covered after query all startup_nodes.
Error message
All slots are not covered after query all startup_nodes. {len(tmp_slots)} of {REDIS_CLUSTER_HASH_SLOTS} covered... What it means
Raised as a RedisClusterException after successfully querying all startup nodes when the combined slot coverage is incomplete (not all 16384 slots are covered) and require_full_coverage is True (the default). The message reports how many of the 16384 slots are covered. The guard is at cluster.py:2783-2790. This prevents the client from starting in a state where some keys would be unroutable.
Solutions
- Fix the cluster so all 16384 slots are covered: use redis-cli --cluster fix or redis-cli --cluster rebalance to assign uncovered slots.
- If you intentionally want to tolerate partial coverage, set require_full_coverage=False (but commands hitting uncovered slots will then fail at execution time with error 210).
- Wait for the cluster to finish creating/resharding and retry the client connection.
Example fix
// before client = RedisCluster(host, port, require_full_coverage=True) # cluster not fully covered // after (tolerate partial coverage) client = RedisCluster(host, port, require_full_coverage=False)
Defensive patterns
Strategy: validation
Validate before calling
import redis
# Check slot coverage before connecting
standalone = redis.Redis(host, port)
slots = standalone.cluster('SLOTS')
covered = set()
for s in slots:
for i in range(int(s[0]), int(s[1]) + 1):
covered.add(i)
if len(covered) < 16384:
missing = set(range(16384)) - covered
print(f'{len(missing)} slots uncovered; fix cluster or set require_full_coverage=False') Type guard
def cluster_has_full_coverage(host: str, port: int) -> bool:
import redis
standalone = redis.Redis(host, port)
slots = standalone.cluster('SLOTS')
covered = set()
for s in slots:
covered.update(range(int(s[0]), int(s[1]) + 1))
return len(covered) == 16384 Try / catch
from redis.exceptions import RedisClusterException
try:
client = RedisCluster(host, port, require_full_coverage=True)
except RedisClusterException as e:
if 'All slots are not covered' in str(e):
# tolerate partial coverage if acceptable
client = RedisCluster(host, port, require_full_coverage=False) Prevention
- Use redis-cli --cluster check to verify all 16384 slots are covered before connecting.
- Run redis-cli --cluster fix to assign uncovered slots.
- Only set require_full_coverage=False if your application tolerates partial slot gaps.
When it happens
Trigger: Constructing RedisCluster(require_full_coverage=True) when the cluster has slots not assigned to any node (e.g., a cluster still being created, or a node holding slots has been removed without reassigning them). check_slots_coverage(tmp_slots) returns False.
Common situations: Cluster creation is incomplete (not all slots assigned), a primary holding slots failed and its slots were not picked up by replicas, or the cluster is mid-resharding during client init.
Related errors
- Cluster mode is not enabled on this node
- Initial connection failed - no active database found
- Initial health check failed. Initial health check policy
- shard channel(s) left unreconciled; slot(s) not covered by…
- Redis Cluster cannot be connected. Please provide at least…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/e64c02ae289ae607.
Report an issue: GitHub.
Appendix: source
Thrown at redis/cluster.py:2786
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()))
# Check if the slots are not fully covered
if not fully_covered and self._require_full_coverage:
# Despite the requirement that the slots be covered, there
# isn't a full coverage
raise RedisClusterException(
f"All slots are not covered after query all startup_nodes. "
f"{len(tmp_slots)} of {REDIS_CLUSTER_HASH_SLOTS} "
f"covered..."
)
# Set the tmp variables to the real variables
with self._lock:
self.nodes_cache = tmp_nodes_cache
self.slots_cache = tmp_slots
# Set the default node
self.default_node = self.get_nodes_by_server_type(PRIMARY)[0]
if self._dynamic_startup_nodes:
# Populate the startup nodes with all discovered nodes
self.startup_nodes = tmp_nodes_cache
# Increment the epoch to signal that initialization has completed
self._epoch += 1
# Dispatch so listeners (e.g. ClusterPubSub) can reconcile per-node
# state after slot ownership may have changed. A listener must notView on GitHub (pinned to 6a6b581b48)