redis/redis-py · error · RedisClusterException
Too many targets for command {c.args}
Error message
Too many targets for command {c.args} What it means
Raised in PipelineStrategy._send_cluster_commands (redis/cluster.py:4296) when _determine_nodes() returns more than one node for a single queued command. The pipeline fan-out logic expects each individual command to be pinned to exactly one node; multi-node fan-out is meant to happen at execute() time via response policies, not by handing one command a list of nodes.
Source
Thrown at redis/cluster.py:4296
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)
try:
connection = get_connection(redis_node)
except (ConnectionError, TimeoutError):
# Release any connections we've already acquired before clearing nodes
for n in nodes.values():View on GitHub (pinned to da03cdc7e8)
Solutions
- Remove the multi-node target_nodes from the pipeline command and let normal slot routing pick one node: pipe.set('k','v').
- If you truly need to broadcast, issue the command through the non-pipeline client: rc.config_rewrite(target_nodes=RedisCluster.ALL_NODES).
- If you need the same command on several nodes in a pipeline, queue one entry per node, each with target_nodes=<single ClusterNode>.
Example fix
# before
pipe = rc.pipeline()
pipe.set('k', 'v', target_nodes=RedisCluster.ALL_NODES) # >1 target
pipe.execute()
# after
rc.set('k', 'v') # single slot via client
# or, per-node in the pipeline:
for n in rc.get_nodes():
pipe.set('k', 'v', target_nodes=n) Defensive patterns
Strategy: validation
Validate before calling
def safe_pipeline_cmd(pipe, method, *args, target=None, **kwargs):
if target is not None and isinstance(target, (list, tuple, set, dict)) and len(target) > 1:
raise ValueError('cluster pipeline accepts a single target node per command')
return getattr(pipe, method)(*args, target_nodes=target, **kwargs) Type guard
from redis.cluster import ClusterNode
def is_single_node(target) -> bool:
return target is None or isinstance(target, ClusterNode) Try / catch
from redis.exceptions import RedisClusterException
try:
pipe.set('k', 'v', target_nodes=RedisCluster.ALL_NODES)
pipe.execute()
except RedisClusterException as e:
if 'Too many targets' in str(e):
for n in rc.get_nodes():
pipe.set('k', 'v', target_nodes=n)
pipe.execute()
else:
raise Prevention
- Never pass multi-node flags (ALL_NODES/PRIMARIES/REPLICAS) to a single pipeline command.
- Queue one command per node if you must broadcast inside a pipeline.
- Reserve multi-node fan-out for the non-pipeline client API.
When it happens
Trigger: Passing an explicit multi-node target to a single pipeline command, e.g. pipe.set('k','v', target_nodes=[node_a, node_b]) or pipe.get('k', target_nodes=RedisCluster.ALL_NODES). The resolver fans out to multiple nodes, which the pipeline rejects.
Common situations: Copy-pasting a non-pipeline client call (where multi-node fan-out is supported) into a pipeline. Misunderstanding that cluster pipelines batch per-command-per-node but do not broadcast one command to many nodes. Forgetting that target_nodes=ALL_NODES/PRIMARIES/REPLICAS on a single pipeline command is invalid.
Related errors
- At least a command with a key is needed to identify a node
- No targets were found to execute {c.args} command on
- method multi() is not supported outside of transactional con
- method discard() is not supported outside of transactional c
- At least a command with a key is needed to identify a node
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/a62e762a450c6b19.json.
Report an issue: GitHub.