redis/jedis · error · IllegalStateException

Cannot use Jedis when in Multi. Please use Transaction or…

Error message

Cannot use Jedis when in Multi. Please use Transaction or reset jedis state.

What it means

Jedis's legacy single-connection client cannot run interactive commands while a MULTI transaction is open on it. checkIsInMultiOrPipeline throws IllegalStateException when the transaction field is non-null to prevent commands from being interleaved into the transaction unintentionally. The message directs you to use the Transaction object for commands or reset the Jedis state.

Solutions

  1. Execute the commands on the Transaction object instead of the Jedis instance (tx.ping() etc.)
  2. Commit (tx.exec()) or abort (tx.close()) the transaction before using jedis directly
  3. Discard/reset state: call jedis.resetState() to clear the multi flag
  4. Avoid sharing one Jedis instance between transactional and direct use; use JedisPool

Example fix

// before
Transaction tx = jedis.multi();
jedis.flushDB(); // IllegalStateException: in Multi
// after
Transaction tx = jedis.multi();
tx.flushDB();
tx.exec();
// or, if the transaction is abandoned:
jedis.resetState();
Defensive patterns

Strategy: validation

Validate before calling

if (jedis.isInMulti()) { // or track your own Transaction reference
  throw new IllegalStateException("complete or reset the transaction first");
}

Try / catch

try {
  jedis.ping();
} catch (IllegalStateException e) {
  if (e.getMessage().startsWith("Cannot use Jedis when in Multi")) {
    jedis.resetState();
    jedis.ping();
  } else throw e;
}

Prevention

When it happens

Trigger: Calling ping/select/swapDB/flushDB/flushAll/copy on a Jedis instance after jedis.multi() was called and before the Transaction was committed/aborted, e.g. doing health-check pings or a flushAll inside the transaction window.

Common situations: Shared Jedis instance used by monitoring code that pings while another thread has opened a transaction; forgetting to exec() or close() a Transaction so the Jedis stays in multi state; calling administrative commands (flushDB) inside transaction blocks for tests.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/972d1314263b46fc. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/Jedis.java:431

      @Override
      protected void onAfterDiscard() {
        resetState();
      }
    };
    return transaction;
  }

  // Legacy
  public Pipeline pipelined() {
    pipeline = new Pipeline(this);
    return pipeline;
  }

  // Legacy
  protected void checkIsInMultiOrPipeline() {
//    if (connection.isInMulti()) {
    if (transaction != null) {
      throw new IllegalStateException(
          "Cannot use Jedis when in Multi. Please use Transaction or reset jedis state.");
    } else if (pipeline != null && pipeline.hasPipelinedResponse()) {
      throw new IllegalStateException(
          "Cannot use Jedis when in Pipeline. Please use Pipeline or reset jedis state.");
    }
  }

  public int getDB() {
    return this.db;
  }

  /**
   * @return <code>PONG</code>
   */
  @Override
  public String ping() {
    checkIsInMultiOrPipeline();
    connection.sendCommand(Command.PING);

View on GitHub (pinned to 6dac31d4c2)