redis/jedis · critical · JedisClusterOperationException
Cluster retry deadline exceeded.
Error message
Cluster retry deadline exceeded.
What it means
During command execution the ClusterCommandExecutor retries failed commands against cluster nodes until an attempt/deadline budget is exhausted. When the wall-clock retry deadline passes, it throws JedisClusterOperationException("Cluster retry deadline exceeded.") carrying the last underlying exception and last node as cause/suppressed context. It means the command could not be completed within the configured timeout despite retries.
Solutions
- Inspect the cause/suppressed JedisConnectionException and lastNode to find the failing node; verify cluster node health with `redis-cli cluster info` / `cluster nodes`.
- Increase the retry deadline/maxAttempts in the cluster client configuration if your workload tolerates longer waits.
- Restore connectivity: restart failed nodes, fix firewall/security-group rules, and confirm slots are fully covered (no 16384-slot gaps).
- Reduce per-attempt timeouts so more attempts fit within the deadline instead of one slow attempt consuming it.
Example fix
// before
RedisClusterClient.create("127.0.0.1:7000")
.build();
// after
RedisClusterClient.create("127.0.0.1:7000")
.socketTimeout(Duration.ofSeconds(2)) // shorter per-attempt timeout
.maxAttempts(20) // more retry budget
.build(); Defensive patterns
Strategy: try-catch
Validate before calling
// verify cluster reachability before issuing commands
try (Jedis j = new Jedis(anyStartupNode)) {
String state = j.clusterInfo();
if (!state.contains("cluster_state:ok")) throw new IllegalStateException("cluster degraded");
} Try / catch
try {
return cluster.get(key);
} catch (JedisClusterOperationException e) {
Throwable cause = e.getCause();
logger.error("deadline exceeded on node {} : {}", e.getLastNode(), cause, e);
throw new ServiceUnavailableException(e);
} Prevention
- Monitor cluster health (cluster_state, node failures) with alerts
- Set per-attempt timeouts well below the retry deadline
- Size maxAttempts to the deadline so attempts aren't truncated
- Use multiple startup nodes from different availability zones
When it happens
Trigger: Persistent connection failures to cluster nodes (MOVED/ASK loops, node down), Redis server unresponsive or network partitioned, while cluster-configured maxAttempts and the deadline elapse inside doExecuteCommand.
Common situations: Redis cluster node down or being failed over; network partition between client and cluster; cluster state degraded (slot not covered); severe latency making each attempt slow so the deadline expires after only a few retries.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Max attempts must be positive for cluster mode
- Retry deadline exceeded.
- Error while checking availability
- Timeout while waiting for health check result
- FAILOVER with force option requires both a timeout and…
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/ac0341ed16bc90f7.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java:300
if (followRedirections) {
log.debug("Redirected by server to {}", jre.getTargetNode());
redirect = jre;
// if MOVED redirection occurred,
if (jre instanceof JedisMovedDataException) {
// it rebuilds cluster's slot cache recommended by Redis cluster specification
provider.renewSlotCache(connection);
}
} else {
// When followRedirections is false, throw the redirection exception immediately
// instead of silently handling or ignoring it
throw jre;
}
consecutiveConnectionFailures = 0;
} finally {
IOUtils.closeQuietly(connection);
}
if (Instant.now().isAfter(deadline)) {
throw new JedisClusterOperationException("Cluster retry deadline exceeded.", lastException,
lastNode);
}
}
JedisClusterOperationException maxAttemptsException =
new JedisClusterOperationException("No more cluster attempts left.", lastException,
lastNode);
throw maxAttemptsException;
}
/**
* WARNING: This method is accessible for the purpose of testing.
* This should not be used or overriden.
*/
@VisibleForTesting
protected <T> T execute(Connection connection, CommandObject<T> commandObject) {
return connection.executeCommand(commandObject);
}View on GitHub (pinned to 6dac31d4c2)