{"record":{"id":"e64c02ae289ae607","repo":"redis/redis-py","slug":"all-slots-are-not-covered-after-query-all-startup-e64c02","errorCode":null,"errorMessage":"All slots are not covered after query all startup_nodes. {len(tmp_slots)} of {REDIS_CLUSTER_HASH_SLOTS} covered...","messagePattern":"All slots are not covered after query all startup_nodes\\. (.+?) of (.+?) covered\\.\\.\\.","errorType":"exception","errorClass":"RedisClusterException","httpStatus":null,"severity":"critical","filePath":"redis/cluster.py","lineNumber":2786,"sourceCode":"                if fully_covered:\n                    # Don't need to continue to the next startup node if all\n                    # slots are covered\n                    break\n\n            if not startup_nodes_reachable:\n                raise RedisClusterException(\n                    f\"Redis Cluster cannot be connected. Please provide at least \"\n                    f\"one reachable node: {str(exception)}\"\n                ) from exception\n\n            # Create Redis connections to all nodes\n            self.create_redis_connections(list(tmp_nodes_cache.values()))\n\n            # Check if the slots are not fully covered\n            if not fully_covered and self._require_full_coverage:\n                # Despite the requirement that the slots be covered, there\n                # isn't a full coverage\n                raise RedisClusterException(\n                    f\"All slots are not covered after query all startup_nodes. \"\n                    f\"{len(tmp_slots)} of {REDIS_CLUSTER_HASH_SLOTS} \"\n                    f\"covered...\"\n                )\n\n            # Set the tmp variables to the real variables\n            with self._lock:\n                self.nodes_cache = tmp_nodes_cache\n                self.slots_cache = tmp_slots\n                # Set the default node\n                self.default_node = self.get_nodes_by_server_type(PRIMARY)[0]\n                if self._dynamic_startup_nodes:\n                    # Populate the startup nodes with all discovered nodes\n                    self.startup_nodes = tmp_nodes_cache\n                # Increment the epoch to signal that initialization has completed\n                self._epoch += 1\n            # Dispatch so listeners (e.g. ClusterPubSub) can reconcile per-node\n            # state after slot ownership may have changed. A listener must not","sourceCodeStart":2768,"sourceCodeEnd":2804,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/cluster.py#L2768-L2804","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nclient = RedisCluster(host, port, require_full_coverage=True)  # cluster not fully covered\n\n// after (tolerate partial coverage)\nclient = RedisCluster(host, port, require_full_coverage=False)","handlingStrategy":"validation","validationCode":"import redis\n# Check slot coverage before connecting\nstandalone = redis.Redis(host, port)\nslots = standalone.cluster('SLOTS')\ncovered = set()\nfor s in slots:\n    for i in range(int(s[0]), int(s[1]) + 1):\n        covered.add(i)\nif len(covered) < 16384:\n    missing = set(range(16384)) - covered\n    print(f'{len(missing)} slots uncovered; fix cluster or set require_full_coverage=False')","typeGuard":"def cluster_has_full_coverage(host: str, port: int) -> bool:\n    import redis\n    standalone = redis.Redis(host, port)\n    slots = standalone.cluster('SLOTS')\n    covered = set()\n    for s in slots:\n        covered.update(range(int(s[0]), int(s[1]) + 1))\n    return len(covered) == 16384","tryCatchPattern":"from redis.exceptions import RedisClusterException\ntry:\n    client = RedisCluster(host, port, require_full_coverage=True)\nexcept RedisClusterException as e:\n    if 'All slots are not covered' in str(e):\n        # tolerate partial coverage if acceptable\n        client = RedisCluster(host, port, require_full_coverage=False)","preventionTips":["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."],"tags":["slot-coverage","initialization","require-full-coverage","cluster-health"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}