How to fix ERR EXEC without MULTI in Redis

RedisINTERMEDIATEHIGHUpdated Dec 25, 2025ยท 115 views

The "ERR EXEC without MULTI" error occurs when attempting to execute EXEC without first starting a transaction with MULTI. This is typically caused by connection switching, premature DISCARD calls, or connection pool issues in client libraries.

Quick fix

Fixes ERR EXEC without MULTI

MULTI          # Starts transaction
SET key1 val1  # Gets queued
SET key2 val2  # Gets queued
EXEC           # Executes all queued commands
  1. Verify MULTI is called before EXEC
  2. Don't call DISCARD before EXEC
  3. Use connection pooling correctly with SessionCallback (Spring/Java)
  4. Verify connection persistence for client libraries
redis โ€” error
MULTI # Starts transaction
SET key1 val1 # Gets queued
SET key2 val2 # Gets queued
EXEC # Executes all queued commands
ERR EXEC without MULTI

What this error means

Redis transactions are entered using the MULTI command, which queues subsequent commands without executing them. The EXEC command then executes all queued commands atomically. When EXEC is called without a corresponding MULTI, Redis returns the "ERR EXEC without MULTI" error because there is no active transaction to execute. This error commonly occurs in three scenarios: directly calling EXEC without MULTI in the Redis CLI, attempting to execute EXEC after issuing DISCARD (which exits the transaction), or experiencing connection multiplexing issues where MULTI and EXEC commands from different transactions get routed to different Redis connections.

Typical symptoms

  • Application receives "ERR EXEC without MULTI" error responses from Redis
  • Errors occur intermittently, especially under load (30+ requests per second)
  • All commands appear correct individually but fail when grouped in a transaction
  • Issue reproduces more frequently with connection pooling or clustering setups

Common causes

  1. Calling EXEC without first calling MULTI to start a transaction
  2. Calling DISCARD to cancel a transaction, then attempting to call EXEC afterward
  3. Connection pooling issues where MULTI and EXEC commands are routed to different Redis connections
  4. Client library not maintaining transaction state properly across pipelined commands
  5. Redis connection reset or failure between MULTI and EXEC commands

How to fix "ERR EXEC without MULTI"

1Verify MULTI is called before EXEC

Ensure your code calls MULTI before any transaction commands, and only calls EXEC after queueing the desired commands.

Correct pattern:

bash
MULTI          # Starts transaction
SET key1 val1  # Gets queued
SET key2 val2  # Gets queued
EXEC           # Executes all queued commands

Incorrect pattern:

bash
SET key1 val1  # Executed immediately
EXEC           # Error: ERR EXEC without MULTI
2Don't call DISCARD before EXEC

DISCARD aborts a transaction and resets the connection state. If you call DISCARD, the transaction is ended and you cannot call EXEC.

Incorrect:

bash
MULTI
SET key1 val1
DISCARD        # Transaction ended
EXEC           # Error: ERR EXEC without MULTI

If you need to cancel a transaction, only call DISCARD and then start a new MULTI/EXEC block if needed.

3Use connection pooling correctly with SessionCallback (Spring/Java)

If using Spring Data Redis or similar libraries, ensure all MULTI/EXEC commands use the same Redis connection. Use SessionCallback or similar transaction support to bind operations to a single connection.

java
redisTemplate.execute(new SessionCallback<List<Object>>() {
    @Override
    public <K, V> List<Object> execute(RedisOperations<K, V> operations)
            throws DataAccessException {
        operations.multi();
        operations.opsForValue().set("key1", "value1");
        operations.opsForValue().set("key2", "value2");
        return operations.exec();
    }
});

This ensures all commands are executed on the same connection instance.

4Verify connection persistence for client libraries

For clients like vert-x3, Lettuce, or Jedis, verify that:

- The same connection is used for MULTI, all queued commands, and EXEC
- Connection pooling doesn't multiplex commands from different transactions onto the same connection
- Enable debugging to trace which connection handles each command

If using load testing, reduce concurrency initially to verify the basic pattern works. Under high load (30+ rps), connection switching becomes more likely.

Advanced notes

Connection multiplexing: Some client libraries multiplex multiple operations across a shared connection pool. This can cause MULTI and EXEC commands from different logical transactions to interleave on the same Redis connection, resulting in EXEC being issued without its corresponding MULTI.

WATCH and optimistic locking: When using WATCH before MULTI for optimistic locking, ensure the WATCH, MULTI, operations, and EXEC all happen on the same connection. If any watched key is modified between WATCH and EXEC, the transaction is aborted and EXEC returns null.

Cluster mode limitations: Redis Cluster does not support the WATCH command. For atomic operations in cluster mode, use Lua scripts instead of MULTI/EXEC.

High-load scenarios: Under heavy load, issues with connection switching become more apparent. Load testing with 30+ requests per second often reveals connection pool bugs that don't appear in normal operation.

Frequently asked questions

What does "ERR EXEC without MULTI" mean?
Redis transactions are entered using the MULTI command, which queues subsequent commands without executing them. The EXEC command then executes all queued commands atomically. When EXEC is called without a corresponding MULTI, Redis returns the "ERR EXEC without MULTI" error because there is no active transaction to execute.
How do I fix "ERR EXEC without MULTI"?
The "ERR EXEC without MULTI" error occurs when attempting to execute EXEC without first starting a transaction with MULTI. This is typically caused by connection switching, premature DISCARD calls, or connection pool issues in client libraries.
What causes "ERR EXEC without MULTI"?
Calling EXEC without first calling MULTI to start a transaction Calling DISCARD to cancel a transaction, then attempting to call EXEC afterward Connection pooling issues where MULTI and EXEC commands are routed to different Redis connections
Is the "ERR EXEC without MULTI" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading