redis/jedis · error · JedisClusterOperationException
Cannot get connection for command with multiple hash slots
Error message
Cannot get connection for command with multiple hash slots
What it means
ClusterConnectionProvider.getConnection() computes the hash slots of all keys in the command; Redis cluster commands must touch exactly one slot, so if the CommandArguments contain keys hashing to more than one slot it throws JedisClusterOperationException instead of sending an invalid cross-slot command.
Solutions
- Split the operation into per-slot commands (group keys by hash slot) and issue one command per slot.
- Use hash tags ({user1000}.field) so related keys colocate in the same slot.
- Use a pipeline on the cluster client (which routes per-slot automatically) instead of a single multi-key command.
Example fix
// before
jedis.mget("user:1", "order:2"); // different slots
// after
jedis.mget("{user:1}:a", "{user:1}:b"); // same slot via hash tag Defensive patterns
Strategy: validation
Validate before calling
Set<Integer> slots = new HashSet<>();
for (String key : keys) slots.add(JedisClusterCRC16.getSlot(SafeEncoder.encode(key)));
if (slots.size() > 1) throw new IllegalArgumentException("Keys span multiple cluster slots: " + slots); Type guard
boolean singleSlot(List<String> keys) { return keys.stream().map(k -> JedisClusterCRC16.getSlot(k.getBytes(StandardCharsets.UTF_8))).distinct().count() <= 1; } Try / catch
try {
return jedis.mget(keys.toArray(new String[0]));
} catch (JedisClusterOperationException e) {
return keys.stream().collect(partitioningBySlot()).values().stream()
.map(group -> jedis.mget(group.toArray(new String[0])))
.flatMap(List::stream).collect(toList());
} Prevention
- Use hash tags ({user123}.field) to colocate related keys.
- Group keys by JedisClusterCRC16.getSlot() before multi-key commands.
- Prefer cluster pipelines over raw multi-key commands.
- Test multi-key paths against a real cluster topology.
When it happens
Trigger: Issuing a multi-key command (e.g. MGET, MSET, SUNION, DEL of several keys, pipelines with multiple keys per command) whose keys hash to different slots on a cluster connection.
Common situations: Multi-key operations after re-sharding moved keys into different slots; pipelines reused between standalone and cluster modes; batch code that assumes all keys share a keytag/prefix.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- No nodes to initialize cluster slots cache.
- setHostAndPort method has limited capability.
- It is not allowed to create Pipeline from this
- It is not allowed to create Transaction from this
- At least one cluster node must be specified for cluster mode
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/595dc506eac2521a.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/providers/ClusterConnectionProvider.java:131
public Map<String, ConnectionPool> getPrimaryNodes() {
return cache.getPrimaryNodes();
}
public HostAndPort getNode(int slot) {
return slot >= 0 ? cache.getSlotNode(slot) : null;
}
public Connection getConnection(HostAndPort node) {
return node != null ? cache.setupNodeIfNotExist(node).getResource() : getConnection();
}
@Override
public Connection getConnection(CommandArguments args) {
Set<Integer> slots = args.getKeyHashSlots();
if (slots.size() > 1) {
throw new JedisClusterOperationException("Cannot get connection for command with multiple hash slots");
}
int slot = slots.iterator().next();
return slot >= 0 ? getConnectionFromSlot(slot) : getConnection();
}
public Connection getReplicaConnection(CommandArguments args) {
Set<Integer> slots = args.getKeyHashSlots();
if (slots.size() > 1) {
throw new JedisClusterOperationException("Cannot get connection for command with multiple hash slots");
}
int slot = slots.iterator().next();
return slot >= 0 ? getReplicaConnectionFromSlot(slot) : getConnection();
}
@OverrideView on GitHub (pinned to 6dac31d4c2)