{"id":"d3ff38515127f427","repo":"redis/redis-py","slug":"no-targets-were-found-to-execute-args-command-on","errorCode":null,"errorMessage":"No targets were found to execute {args} command on","messagePattern":"No targets were found to execute (.+?) command on","errorType":"exception","errorClass":"RedisClusterException","httpStatus":null,"severity":"error","filePath":"redis/asyncio/cluster.py","lineNumber":1185,"sourceCode":"            if self._initialize:\n                await self.initialize(last_failed_node_name=last_failed_node_name)\n                last_failed_node_name = None\n                if (\n                    len(target_nodes) == 1\n                    and target_nodes[0] == self.get_default_node()\n                ):\n                    # Replace the default cluster node\n                    self.replace_default_node()\n            try:\n                if not target_nodes_specified:\n                    # Determine the nodes to execute the command on\n                    target_nodes = await self._determine_nodes(\n                        *args,\n                        request_policy=command_policies.request_policy,\n                        node_flag=passed_targets,\n                    )\n                    if not target_nodes:\n                        raise RedisClusterException(\n                            f\"No targets were found to execute {args} command on\"\n                        )\n\n                if len(target_nodes) == 1:\n                    # Return the processed result\n                    ret = await self._execute_command(target_nodes[0], *args, **kwargs)\n                    if command in self.result_callbacks:\n                        ret = self.result_callbacks[command](\n                            command, {target_nodes[0].name: ret}, **kwargs\n                        )\n                    return self._policies_callback_mapping[\n                        command_policies.response_policy\n                    ](ret)\n                else:\n                    keys = [node.name for node in target_nodes]\n                    values = await asyncio.gather(\n                        *(\n                            asyncio.create_task(","sourceCodeStart":1167,"sourceCodeEnd":1203,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/asyncio/cluster.py#L1167-L1203","documentation":"Raised in execute_command() when _determine_nodes() returns an empty list and no target_nodes were explicitly supplied. This means the request policy resolved to zero candidate nodes — typically because the cluster topology has no nodes of the required server type, or the routing policy produced nothing usable.","triggerScenarios":"Issuing a replica-routed command (read_from_replicas=True) when the cluster has no replicas; a command whose policy targets ALL_NODES/REPLICAS but the slots cache or nodes cache is empty/degraded; a transient state during resharding where the relevant node group is momentarily empty.","commonSituations":"Enabling read_from_replicas against a single-node or no-replica cluster; querying immediately after a failover before topology refresh; a misconfigured cluster where replicas are not registered in CLUSTER SLOTS output.","solutions":["Pass target_nodes explicitly to bypass policy resolution: target_nodes=RedisCluster.PRIMARIES.","If read_from_replicas=True, ensure the cluster actually has replica nodes (check CLUSTER NODES); set read_from_replicas=False if not.","Call await rc.refresh_nodes() / reconnect to refresh topology, then retry the command."],"exampleFix":"// before\nrc = RedisCluster.from_url(url, read_from_replicas=True)\nawait rc.get('k')\n\n// after\nrc = RedisCluster.from_url(url, read_from_replicas=False)\nawait rc.get('k')","handlingStrategy":"fallback","validationCode":"async def read_with_fallback(rc, key):\n    if rc.read_from_replicas:\n        replicas = rc.get_nodes_by_server_type('replica')\n        if not replicas:\n            # no replicas — route to a primary instead\n            return await rc.get(key, target_nodes=RedisCluster.PRIMARIES)\n    return await rc.get(key)","typeGuard":"from redis.asyncio.cluster import RedisCluster\n\ndef has_routing_targets(rc: RedisCluster) -> bool:\n    return bool(rc.get_primaries()) or bool(rc.get_replicas())","tryCatchPattern":"from redis.cluster import RedisClusterException\n\ntry:\n    await rc.get('k')\nexcept RedisClusterException as e:\n    if 'No targets' in str(e):\n        await rc.refresh_table_nodes()  # or reload_exception()\n        await rc.get('k', target_nodes=RedisCluster.PRIMARIES)\n    else:\n        raise","preventionTips":["Before enabling read_from_replicas, confirm replicas exist via CLUSTER NODES.","Build a retry wrapper that refreshes topology and falls back to PRIMARIES when no targets resolve.","Monitor cluster topology health so degraded replica sets are caught early."],"tags":["redis-cluster","routing","no-targets","replicas"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}