redis/redis-py · error · RedisClusterException

Too many targets for command {cmd.args}

Error message

Too many targets for command {cmd.args}

What it means

Raised in the pipeline execute path when a single queued command resolves to more than one target node. The cluster pipeline groups commands by destination node and executes each node's batch in one round-trip; a command that fans out to multiple nodes (e.g. an ALL_NODES policy command) cannot be placed in a single per-node batch, so it is rejected.

Source

Thrown at redis/asyncio/cluster.py:2944

                                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()
            )
        )

        # Record operation duration for each node
        for node_name, (node, commands) in nodes.items():
            # Find the first error in this node's commands, if any

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Remove fan-out commands from the pipeline; issue them separately with target_nodes=ALL_NODES / PRIMARIES.
  2. Pass a single ClusterNode (or single-slot key set) so the command resolves to exactly one node.
  3. Split the pipeline so each queued command's keys share one slot and one target.

Example fix

// before
pipe = rc.pipeline()
pipe.flushdb()  # fan-out, resolves to all primaries
pipe.set('k', 'v')
await pipe.execute()

// after
pipe = rc.pipeline()
pipe.set('k', 'v')
await pipe.execute()
await rc.flushdb(target_nodes=RedisCluster.PRIMARIES)
Defensive patterns

Strategy: validation

Validate before calling

FAN_OUT_COMMANDS = {'FLUSHDB', 'FLUSHALL', 'CONFIG', 'CLIENT', 'CLUSTER', 'BGSAVE', 'BGREWRITEAOF'}

def split_pipeline_commands(rc, commands):
    pipe = rc.pipeline()
    deferred = []
    for cmd, args in commands:
        if cmd.upper().split()[0] in FAN_OUT_COMMANDS:
            deferred.append((cmd, args))
        else:
            getattr(pipe, cmd.lower())(*args)
    return pipe, deferred

Type guard

from redis.asyncio.cluster import ClusterNode

def command_targets_single_node(target_nodes) -> bool:
    if isinstance(target_nodes, ClusterNode):
        return True
    if isinstance(target_nodes, list):
        return len(target_nodes) <= 1
    return False  # flag strings like ALL_NODES are multi-target

Try / catch

from redis.cluster import RedisClusterException

pipe = rc.pipeline()
pipe.flushdb()
try:
    await pipe.execute()
except RedisClusterException as e:
    if 'Too many targets' in str(e):
        await rc.flushdb(target_nodes=RedisCluster.PRIMARIES)
    else:
        raise

Prevention

When it happens

Trigger: Queuing a command with an ALL_NODES/PRIMARIES request policy in a pipeline (e.g. pipe.config_get(), pipe.flushdb() with fan-out); passing target_nodes=[node1, node2] (a multi-node list) to a single pipelined command.

Common situations: Treating a cluster pipeline like a standalone pipeline and queuing admin/fan-out commands; passing a list of nodes where a single node is required; misunderstanding that pipeline commands must be single-shard.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/ad98db08b98985a6.json. Report an issue: GitHub.