redis/redis-py · error · RedisClusterException
method multi() is not supported outside of transactional…
Error message
method multi() is not supported outside of transactional context
What it means
ClusterPipeline.multi() is a hard error in the non-transactional PipelineStrategy: cluster pipelines created without transaction=True cannot enter a MULTI block, so calling multi() is treated as a programmer mistake. The transactional strategy (TransactionStrategy) is what actually drives MULTI/EXEC inside execute().
Solutions
- Create the pipeline with transaction=True: rc.pipeline(transaction=True) and let execute() wrap the queued commands in MULTI/EXEC automatically.
- Do not call multi() explicitly; queue commands directly on the pipeline.
- Remove any legacy pipe.multi() call when migrating to the cluster pipeline.
Example fix
// before
pipe = rc.pipeline()
pipe.multi() # raises
pipe.set('a', 1)
await pipe.execute()
// after
pipe = rc.pipeline(transaction=True)
pipe.set('a', 1)
await pipe.execute() # MULTI/EXEC handled internally Defensive patterns
Strategy: validation
Validate before calling
def transactional_pipeline(rc, transaction=True):
pipe = rc.pipeline(transaction=transaction)
# do NOT call pipe.multi(); execute() handles MULTI/EXEC
return pipe Type guard
null
Try / catch
from redis.exceptions import RedisClusterException
try:
pipe.multi()
except RedisClusterException as e:
if 'multi() is not supported' in str(e):
# recreate as transactional; do not call multi() explicitly
pipe = rc.pipeline(transaction=True) Prevention
- Create cluster pipelines with transaction=True when you want MULTI/EXEC.
- Never call multi() explicitly on a cluster pipeline.
- Refactor migrated standalone code to drop the explicit multi() call.
When it happens
Trigger: Calling pipe.multi() on a pipeline obtained from rc.pipeline() or rc.pipeline(transaction=False). The default cluster pipeline is non-transactional and never supports an explicit multi().
Common situations: Porting standalone-client code that calls pipe.multi() to mark the start of a transaction; misunderstanding that cluster pipelines handle transactions via the transaction=True flag, not an explicit multi() call.
Related errors
- All keys involved in a cluster transaction must map to the…
- Cannot issue a WATCH after a MULTI
- 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
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/5f8f4e6c76a6c5f4.
Report an issue: GitHub.
Appendix: source
Thrown at redis/asyncio/cluster.py:3033
# Note: when the error is raised we'll reset the default node in the
# caller function.
for cmd in default_node[1]:
# Check if it has a command that failed with a relevant
# exception
if type(cmd.result) in RedisCluster.ERRORS_ALLOW_RETRY:
client.replace_default_node()
break
return [cmd.result for cmd in stack]
async def reset(self):
"""
Reset back to empty pipeline.
"""
self._command_queue = []
def multi(self):
raise RedisClusterException(
"method multi() is not supported outside of transactional context"
)
async def watch(self, *names):
raise RedisClusterException(
"method watch() is not supported outside of transactional context"
)
async def unwatch(self):
raise RedisClusterException(
"method unwatch() is not supported outside of transactional context"
)
async def discard(self):
raise RedisClusterException(
"method discard() is not supported outside of transactional context"
)
View on GitHub (pinned to 6a6b581b48)