redis/redis-py · error · RedisClusterException

No targets were found to execute

Error message

No targets were found to execute {args} command on

What it means

Raised inside the main execute_command path when _determine_nodes() returns an empty list for a command. The policy callback resolved to zero candidate nodes, so there is nowhere to send the command and the client refuses rather than silently dropping it.

Solutions

  1. Ensure the cluster is initialised (await rc.initialize()) before issuing commands, or rely on the auto-init that execute_command triggers.
  2. If targeting replicas, confirm replicas exist (rc.get_nodes(); server_type == 'replica') before using rc.REPLICAS.
  3. Re-issue the command after topology refresh; if it persists, inspect rc.get_nodes() to see what the cache actually contains.
  4. Fall back to an explicit target_nodes= argument pointing at a known-good primary.

Example fix

// before
await rc.execute_command('GET', 'x', target_nodes=rc.REPLICAS)  # no replicas exist

// after
await rc.initialize()
nodes = rc.get_nodes()
if any(n.server_type == 'replica' for n in nodes.values()):
    await rc.execute_command('GET', 'x', target_nodes=rc.REPLICAS)
else:
    await rc.execute_command('GET', 'x')
Defensive patterns

Strategy: validation

Validate before calling

async def ensured_execute(rc, *args, **kwargs):
    await rc.initialize()
    if kwargs.get('target_nodes') == rc.REPLICAS and not rc.get_replicas():
        kwargs['target_nodes'] = rc.PRIMARIES
    return await rc.execute_command(*args, **kwargs)

Type guard

null

Try / catch

from redis.exceptions import RedisClusterException
for _ in range(3):
    try:
        return await rc.execute_command(*args, **kwargs)
    except RedisClusterException as e:
        if 'No targets were found' not in str(e):
            raise
        await rc.initialize()
raise RuntimeError('no targets after refresh')

Prevention

When it happens

Trigger: A command whose policy resolves to a node group that is currently empty in the cache, e.g. requesting REPLICAS when no replicas are known, or ALL_NODES before initialize() completed; also possible right after all primaries were removed during a refresh.

Common situations: Cluster with no replicas deployed but read_from_replicas=True and a replica-routed command; running commands before await rc.initialize() finished; transient empty cache during failover.

Related errors


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

Appendix: source

Thrown at redis/asyncio/cluster.py:1186

            if self._initialize:
                await self.initialize(last_failed_node_name=last_failed_node_name)
                last_failed_node_name = None
                if (
                    len(target_nodes) == 1
                    and target_nodes[0] == self.get_default_node()
                ):
                    # Replace the default cluster node
                    self.replace_default_node()
            try:
                if not target_nodes_specified:
                    # Determine the nodes to execute the command on
                    target_nodes = await self._determine_nodes(
                        *args,
                        request_policy=command_policies.request_policy,
                        node_flag=passed_targets,
                    )
                    if not target_nodes:
                        raise RedisClusterException(
                            f"No targets were found to execute {args} command on"
                        )

                if len(target_nodes) == 1:
                    # Return the processed result
                    ret = await self._execute_command(target_nodes[0], *args, **kwargs)
                    if command in self.result_callbacks:
                        ret = self.result_callbacks[command](
                            command, {target_nodes[0].name: ret}, **kwargs
                        )
                    return self._policies_callback_mapping[
                        command_policies.response_policy
                    ](ret)
                else:
                    keys = [node.name for node in target_nodes]
                    values = await asyncio.gather(
                        *(
                            asyncio.create_task(

View on GitHub (pinned to 6a6b581b48)