redis/redis-py · error · RedisClusterException
No targets were found to execute {cmd.args} command on
Error message
No targets were found to execute {cmd.args} command on What it means
The pipeline-execution analogue of error 65: raised inside the pipeline execute path when _determine_nodes() returns an empty list for a queued command. A pipeline command must resolve to at least one target node; zero means the routing policy found no candidate (e.g. replica policy with no replicas, or empty node group) and the pipeline cannot place the command.
Source
Thrown at redis/asyncio/cluster.py:2939
response_policy=ResponsePolicy.DEFAULT_KEYED,
)
else:
if command_flag in client._command_flags_mapping:
command_policies = CommandPolicies(
request_policy=client._command_flags_mapping[
command_flag
]
)
else:
command_policies = CommandPolicies()
target_nodes = await client._determine_nodes(
*cmd.args,
request_policy=command_policies.request_policy,
node_flag=passed_targets,
)
if not target_nodes:
raise RedisClusterException(
f"No targets were found to execute {cmd.args} command on"
)
cmd.command_policies = command_policies
if len(target_nodes) > 1:
raise RedisClusterException(f"Too many targets for command {cmd.args}")
node = target_nodes[0]
if node.name not in nodes:
nodes[node.name] = (node, [])
nodes[node.name][1].append(cmd)
# Start timing for observability
start_time = time.monotonic()
errors = await asyncio.gather(
*(
asyncio.create_task(node[0].execute_pipeline(node[1]))
for node in nodes.values()
)View on GitHub (pinned to da03cdc7e8)
Solutions
- Pass target_nodes explicitly on the pipeline command so routing bypasses policy resolution.
- If using read_from_replicas, ensure replicas exist (CLUSTER NODES) or set read_from_replicas=False.
- Refresh topology (await rc.refresh_nodes()) and retry the pipeline after failover completes.
Example fix
// before
pipe = rc.pipeline()
pipe.get('k')
await pipe.execute() # read_from_replicas=True, no replicas
// after
pipe = rc.pipeline()
pipe.get('k', target_nodes=RedisCluster.PRIMARIES)
await pipe.execute() Defensive patterns
Strategy: fallback
Validate before calling
async def pipelined_read(rc, key):
if rc.read_from_replicas and not rc.get_replicas():
pipe = rc.pipeline()
pipe.get(key, target_nodes=RedisCluster.PRIMARIES)
return (await pipe.execute())[0]
pipe = rc.pipeline()
pipe.get(key)
return (await pipe.execute())[0] Type guard
from redis.asyncio.cluster import RedisCluster
def pipeline_has_targets(rc: RedisCluster) -> bool:
return bool(rc.get_primaries()) Try / catch
from redis.cluster import RedisClusterException
pipe = rc.pipeline()
pipe.get('k')
try:
await pipe.execute()
except RedisClusterException as e:
if 'No targets' in str(e):
await rc.refresh_table_nodes()
pipe = rc.pipeline()
pipe.get('k', target_nodes=RedisCluster.PRIMARIES)
await pipe.execute()
else:
raise Prevention
- Pass target_nodes explicitly on pipeline commands when topology may be degraded.
- Don't enable read_from_replicas without confirming replicas exist.
- Refresh topology before flushing long-lived pipelines after a failover.
When it happens
Trigger: Queuing a replica-routed read in a pipeline when the cluster has no replicas; a pipeline command whose policy targets a node group that is empty in the current topology; transient empty node set during failover when the pipeline flushes.
Common situations: read_from_replicas=True with no replicas present; long-lived pipeline that buffers commands while topology changes underneath; pipeline issued right after client construction before topology settled.
Related errors
- No targets were found to execute {args} command on
- Cannot execute FT.CURSOR commands without FT.AGGREGATE
- No way to dispatch this command to Redis Cluster. Missing ke
- shard_hint is deprecated in cluster mode
- Too many targets for command {cmd.args}
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/860ade2484c2cfc4.json.
Report an issue: GitHub.