redis/jedis · error · JedisDataException
Unexpected response
Error message
Unexpected response: ${response} What it means
During exec(), MultiDbTransaction issues MULTI on the acquired connection and expects an 'OK' reply. If the server returns anything else (a Redis error like WRONGTYPE-encoded response, a proxy-injected error, or an unexpected object), it throws JedisDataException("Unexpected response: <reply>") and aborts before sending the queued commands.
Solutions
- Discard the transaction, obtain a fresh transaction/connection, and retry the whole multi()/commands/exec() cycle
- Check server/proxy support for MULTI on the endpoint being used
- Catch JedisDataException in exec() paths and log the raw reply to identify the server-side cause
Example fix
// before
List<Object> res = transaction.exec(); // may throw on bad MULTI reply
// after
try {
List<Object> res = transaction.exec();
} catch (JedisDataException e) {
transaction.close();
transaction = client.transaction();
transaction.multi();
// re-issue commands and exec again
} Defensive patterns
Strategy: retry
Try / catch
try { res = t.exec(); } catch (JedisDataException e) { t.close(); /* rebuild transaction and retry once */ } Prevention
- Ensure the endpoint supports MULTI/EXEC (beware proxies)
- Use fresh connections/transactions after failover events
- Log the unexpected reply text included in the exception for root-cause analysis
When it happens
Trigger: The server replies to MULTI with something other than +OK — e.g. the connection is actually in an error state, a proxy/cluster intercepted MULTI, the connection was switched to a different database mid-transaction, or a previous error left the protocol stream misaligned.
Common situations: Failover replaced the underlying connection mid-transaction; running against a proxy (e.g. Redis Enterprise REST-managed endpoints) that rejects MULTI; stale connection after a network blip.
Related errors
- Unknown message type
- Unknown message type:
- WATCH inside MULTI is not allowed
- Active database has changed since transaction started
- EXEC without MULTI
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/e3a7dd01b996f0d2.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/mcf/MultiDbTransaction.java:154
}
}
@Override
public final List<Object> exec() {
if (!inMulti) {
throw new IllegalStateException("EXEC without MULTI");
}
boolean serverInMultiMode = false;
try {
Connection conn = acquireConnection();
Object multiReply = conn
.executeCommand(new CommandObject<>(new CommandArguments(MULTI), NO_OP_BUILDER));
if (!bytesEquals(OK_IN_BYTES, multiReply)) {
Object response = multiReply instanceof byte[] ? SafeEncoder.encode((byte[]) multiReply)
: multiReply;
throw new JedisDataException("Unexpected response: " + response);
}
serverInMultiMode = true;
commands.forEach((command) -> conn.sendCommand(command.getKey()));
// following connection.getMany(int) flushes anyway, so no flush here.
// server replies QUEUED OR ERROR for each buffered command
List<Object> queuedCmdResponses = conn.getMany(commands.size());
if (!connectionSupplier.isActiveDatabase(initialDatabase)) {
JedisException dbSwitchException = new JedisException(
"Active database has changed since transaction started");
try {
conn.executeCommand(new CommandArguments(DISCARD));
serverInMultiMode = false;
} catch (Exception e) {
dbSwitchException.addSuppressed(e);View on GitHub (pinned to 6dac31d4c2)