redis/redis-py · error · RedisClusterException

No targets were found to execute

Error message

No targets were found to execute {c.args} command on

What it means

Raised in PipelineStrategy.send_cluster_commands (redis/cluster.py:4313) when _determine_nodes returns an empty list, meaning no cluster node matched the command's routing policy. The pipeline needs exactly one target node per stacked command, so an empty result means the command could not be placed on any node given the current slot map and request policy.

Solutions

  1. Verify the cluster actually has nodes of the requested role (rc.cluster_nodes()) before targeting replicas/primaries explicitly.
  2. Allow the library to auto-route by not passing target_nodes, or pass target_nodes='primaries' when replicas are absent.
  3. Trigger a topology refresh (rc.cluster_forces_reread() / recreate the client) if the slot map is stale after a reshard.
  4. Ensure the command is recognized by COMMAND INFO; for custom/module commands register the policy or pass an explicit target_node.

Example fix

// before
with rc.pipeline() as pipe:
    pipe.execute_command('GET', 'x', target_nodes='replicas')
    pipe.execute()
// after
with rc.pipeline() as pipe:
    pipe.get('x')  # let cluster route to a primary or available replica
    pipe.execute()
Defensive patterns

Strategy: validation

Validate before calling

primaries = rc.get_primaries()
if primaries:
    with rc.pipeline() as pipe:
        pipe.execute_command('GET', 'x', target_nodes='primaries')
        pipe.execute()

Type guard

def has_nodes_of_role(rc, role: str) -> bool:
    import redis.cluster as c
    getter = {'primaries': rc.get_primaries, 'replicas': rc.get_replicas}[role]
    return len(getter()) > 0

Try / catch

from redis.exceptions import RedisClusterException
try:
    pipe.execute()
except RedisClusterException as e:
    if 'No targets were found' in str(e):
        rc.cluster_forces_reread()  # refresh topology, then retry

Prevention

When it happens

Trigger: Executing a pipeline command whose request policy resolves to zero nodes, e.g. a command flagged for REPLICAS when no replicas are known, or a keyed command whose slot maps to a node that has dropped out of the topology during execution. Also when a keyless command has no predefined flag and the DEFAULT_KEYLESS policy returns no nodes.

Common situations: Cluster with no replicas configured but code requests target_nodes='replicas'; topology refresh race where the cluster is mid-resharding/down; custom commands not registered in COMMAND INFO so the library cannot infer routing.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/985a39461c0cf9ec. Report an issue: GitHub.

Appendix: source

Thrown at redis/cluster.py:4313

                                        response_policy=ResponsePolicy.DEFAULT_KEYED,
                                    )
                        else:
                            if command_flag in self._pipe._command_flags_mapping:
                                command_policies = CommandPolicies(
                                    request_policy=self._pipe._command_flags_mapping[
                                        command_flag
                                    ]
                                )
                            else:
                                command_policies = CommandPolicies()

                    target_nodes = self._determine_nodes(
                        *c.args,
                        request_policy=command_policies.request_policy,
                        node_flag=passed_targets,
                    )
                    if not target_nodes:
                        raise RedisClusterException(
                            f"No targets were found to execute {c.args} command on"
                        )
                c.command_policies = command_policies
                if len(target_nodes) > 1:
                    raise RedisClusterException(
                        f"Too many targets for command {c.args}"
                    )

                node = target_nodes[0]
                if node == self._pipe.get_default_node():
                    is_default_node = True

                # now that we know the name of the node
                # ( it's just a string in the form of host:port )
                # we can build a list of commands for each node.
                node_name = node.name
                if node_name not in nodes:
                    redis_node = self._pipe.get_redis_connection(node)

View on GitHub (pinned to 6a6b581b48)