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

  1. Call the blocked command directly on the client (not through the pipeline): client.keys('*') instead of pipe.keys('*').
  2. For multi-key commands like MGET/SCAN, execute them per-node by targeting specific nodes with target_nodes, or iterate over get_primaries().
  3. 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

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


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)