redis/redis-py · error · RedisClusterException
ERROR: Calling pipelined function
Error message
ERROR: Calling pipelined function {name} is blocked when running redis in cluster mode... What it means
Raised as a RedisClusterException by the block_pipeline_command wrapper (cluster.py:3752-3764) when a command listed in PIPELINE_BLOCKED_COMMANDS is called on a ClusterPipeline instance. These commands (BGREWRITEAOF, CONFIG, FLUSHALL, KEYS, MGET, SCAN, SCRIPT, SHUTDOWN, SORT, etc. — ~60 commands) cannot be safely pipelined in cluster mode because they are multi-node, stateful, or semantically incompatible with the pipeline abstraction. The wrapper is installed via setattr at cluster.py:3853-3856.
Solutions
- Call the blocked command directly on the client (not through the pipeline): client.keys('*') instead of pipe.keys('*').
- For multi-key commands like MGET/SCAN, execute them per-node by targeting specific nodes with target_nodes, or iterate over get_primaries().
- For truly batched key operations, use individual pipe.get(key) / pipe.set(key, val) calls (which are supported) and then pipe.execute().
Example fix
// before
pipe = client.pipeline()
pipe.keys('*')
pipe.execute()
// after
all_keys = []
for node in client.get_primaries():
all_keys.extend(client.keys('*', target_nodes=[node])) Defensive patterns
Strategy: validation
Validate before calling
from redis.cluster import PIPELINE_BLOCKED_COMMANDS
blocked_lower = {c.replace(' ', '_').lower() for c in PIPELINE_BLOCKED_COMMANDS}
def safe_pipeline_call(pipe, method_name, *args, **kwargs):
if method_name.lower() in blocked_lower:
raise ValueError(f'{method_name} is blocked in cluster pipeline; call on client directly')
return getattr(pipe, method_name)(*args, **kwargs) Type guard
def is_pipeline_blocked(method_name: str) -> bool:
from redis.cluster import PIPELINE_BLOCKED_COMMANDS
blocked = {c.replace(' ', '_').lower() for c in PIPELINE_BLOCKED_COMMANDS}
return method_name.lower() in blocked Try / catch
from redis.exceptions import RedisClusterException
try:
pipe.keys('*')
except RedisClusterException as e:
if 'is blocked' in str(e):
result = client.keys('*') # call on client, not pipeline Prevention
- Check PIPELINE_BLOCKED_COMMANDS before calling a command on a cluster pipeline.
- Call blocked commands directly on the client, not through the pipeline.
- For multi-node commands like KEYS/SCAN, iterate over get_primaries() with target_nodes.
When it happens
Trigger: Calling pipe.keys('*'), pipe.config_set(...), pipe.flushdb(), pipe.scan(), pipe.mget(...), or any of the ~60 blocked commands on a pipeline obtained from client.pipeline() in cluster mode.
Common situations: Porting pipelined batch code from standalone Redis to cluster mode, or attempting to pipeline admin/diagnostic commands.
Related errors
- All keys involved in a cluster transaction must map to the…
- At least a command with a key is needed to identify a node
- At least a command with a key is needed to identify a node
- Cannot identify slot number for command
- Cannot identify slot number for command
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/e7f0904d20e6e089.
Report an issue: GitHub.
Appendix: source
Thrown at redis/cluster.py:3759
def script_load_for_pipeline(self, *args, **kwargs):
self._execution_strategy.script_load_for_pipeline(*args, **kwargs)
def delete(self, *names):
self._execution_strategy.delete(*names)
def unlink(self, *names):
self._execution_strategy.unlink(*names)
def block_pipeline_command(name: str) -> Callable[..., Any]:
"""
Prints error because some pipelined commands should
be blocked when running in cluster-mode
"""
def inner(*args, **kwargs):
raise RedisClusterException(
f"ERROR: Calling pipelined function {name} is blocked "
f"when running redis in cluster mode..."
)
return inner
def is_zero_key_eval_command(*args) -> bool:
"""
True for EVAL/EVALSHA with numkeys=0 (any primary).
"""
if len(args) < 3:
return False
if str(args[0]).upper() not in ("EVAL", "EVALSHA"):
return False
try:
return int(args[2]) == 0
except (TypeError, ValueError):View on GitHub (pinned to 6a6b581b48)