How to fix ERR EXEC without MULTI in Redis

RedisINTERMEDIATEMEDIUMUpdated Dec 29, 2025· 130 views

This error occurs when EXEC is called without first starting a transaction with MULTI. It typically happens due to connection loss or improper transaction handling in client libraries. Fix it by ensuring MULTI is called before EXEC and using connection pooling.

Quick fix

Fixes ERR EXEC without MULTI

MULTI
[queued commands]
EXEC
  1. Verify MULTI is called before EXEC
  2. Use SessionCallback in Spring Redis
  3. Enable connection pooling and increase pool size
  4. Implement retry logic with exponential backoff
redis — error
MULTI
[queued commands]
EXEC
ERR EXEC without MULTI

What this error means

The "ERR EXEC without MULTI" error means you attempted to execute the EXEC command without first calling MULTI to begin a transaction. In Redis, transactions are started with MULTI, which puts the connection into a transaction mode where subsequent commands are queued instead of executed immediately. When you call EXEC, all queued commands are executed atomically. If EXEC is called outside of this context, Redis rejects it with this error. This error is fundamentally about mismatched transaction boundaries—the server is waiting for MULTI to initiate a transaction block, but received EXEC instead.

Typical symptoms

  • Redis client operations fail with "ERR EXEC without MULTI" error
  • Spring Redis or other client libraries throw transaction exceptions
  • Error occurs intermittently during high concurrency or load testing
  • Connection drops between MULTI and EXEC commands
  • Multiple rapid requests overwhelm the connection pool

Common causes

  1. Connection loss or disconnection between MULTI and EXEC commands
  2. Connection pool exhaustion—connection used for MULTI is different from the one used for EXEC
  3. Spring Data Redis or other client library not using SessionCallback or dedicated transaction connection
  4. Server restart between MULTI and EXEC (transaction context lost)
  5. Improper use of connection pooling in multi-threaded applications
  6. Batch operations exceeding connection timeout or buffer limits

How to fix "ERR EXEC without MULTI"

1Verify MULTI is called before EXEC

Review your code to ensure that every EXEC is preceded by a MULTI command. The basic transaction pattern should always be:

bash
MULTI
[queued commands]
EXEC

If you call EXEC without MULTI, Redis cannot process it. Use a try-finally block to ensure proper cleanup:

javascript
client.multi();
try {
  client.set("key1", "value1");
  client.set("key2", "value2");
  await client.exec();
} catch (err) {
  client.discard();
  throw err;
}
2Use SessionCallback in Spring Redis

If using Spring Data Redis, the most common cause is that different connections are used for MULTI and EXEC. Spring Data Redis uses a connection pool, and each command may use a different connection by default. Use SessionCallback to ensure all transaction commands use the same connection:

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

SessionCallback ensures that watch, multi, and exec all run on the same Redis connection, preventing the "EXEC without MULTI" error.

3Enable connection pooling and increase pool size

If errors occur during high load or concurrency, your connection pool may be exhausted. Monitor and increase the pool size in your Redis client configuration:

For Jedis (Spring Redis):

java
@Bean
public JedisPoolConfig jedisPoolConfig() {
  JedisPoolConfig config = new JedisPoolConfig();
  config.setMaxTotal(100);       // Max connections
  config.setMaxIdle(20);         // Max idle connections
  config.setMinIdle(10);         // Min idle connections
  config.setTestOnBorrow(true);
  config.setTestOnReturn(true);
  return config;
}

For Node.js Redis:

javascript
const client = redis.createClient({
  socket: {
    maxRetriesPerRequest: null,
    enableReadyCheck: false,n  },
});
4Implement retry logic with exponential backoff

For intermittent errors during transient connection issues, implement retry logic:

javascript
async function executeTransaction(client, commands) {
  let retries = 3;
  let lastError;
  
  while (retries > 0) {
    try {
      const pipeline = client.pipeline();
      pipeline.multi();
      commands.forEach(cmd => pipeline[cmd.name](...cmd.args));
      const result = await pipeline.exec();
      return result;
    } catch (err) {
      lastError = err;
      retries--;
      if (retries > 0) {
        await new Promise(resolve => setTimeout(resolve, Math.pow(2, 3 - retries) * 100));
      }
    }
  }
  throw lastError;
}
5Check for connection drops or server restarts

The "EXEC without MULTI" error can also occur if the Redis server restarts between MULTI and EXEC. Implement connection monitoring to detect and handle disconnections:

javascript
client.on("error", (err) => {
  console.error("Redis error:", err);
  // Optionally reconnect
});

client.on("reconnecting", () => {
  console.log("Attempting to reconnect to Redis...");
});

Ensure your client library is configured to automatically reconnect on connection loss. Most modern clients (ioredis, node-redis 4+) handle this by default.

Advanced notes

For Redis Cluster deployments, WATCH and MULTI/EXEC have limitations across different slots. In cluster mode, consider using Lua scripts for atomic operations instead of relying on transactions. Lua scripts execute atomically on the server side without the complexity of MULTI/EXEC coordination. Additionally, be aware that Redis does not support transaction rollbacks—if a command fails during EXEC, subsequent commands still execute. This is by design for performance reasons.

Frequently asked questions

What does "ERR EXEC without MULTI" mean?
The "ERR EXEC without MULTI" error means you attempted to execute the EXEC command without first calling MULTI to begin a transaction. In Redis, transactions are started with MULTI, which puts the connection into a transaction mode where subsequent commands are queued instead of executed immediately. When you call EXEC, all queued commands are executed atomically.
How do I fix "ERR EXEC without MULTI"?
This error occurs when EXEC is called without first starting a transaction with MULTI. It typically happens due to connection loss or improper transaction handling in client libraries. Fix it by ensuring MULTI is called before EXEC and using connection pooling.
What causes "ERR EXEC without MULTI"?
Connection loss or disconnection between MULTI and EXEC commands Connection pool exhaustion—connection used for MULTI is different from the one used for EXEC Spring Data Redis or other client library not using SessionCallback or dedicated transaction connection
Is the "ERR EXEC without MULTI" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading