redisson/redisson · error · InvalidDataAccessResourceUsageException
Clustered rename is not supported in a pipeline
Error message
Clustered rename is not supported in a pipeline
What it means
In cluster mode, RENAME works only when source and destination hash to the same slot. Redisson implements cross-slot rename manually (DUMP the value, read TTL, RESTORE at the new key, DEL the old) — a multi-step, non-atomic sequence that cannot be buffered in a pipeline. Therefore rename() inside an open pipeline throws InvalidDataAccessResourceUsageException.
Source
Thrown at redisson-spring/redisson-spring-data/redisson-spring-data-24/src/main/java/org/redisson/spring/data/connection/RedissonClusterConnection.java:433
RFuture<ListScanResult<byte[]>> f = executorService.readAsync(client, ByteArrayCodec.INSTANCE, RedisCommands.SCAN, args.toArray());
ListScanResult<byte[]> res = syncFuture(f);
String pos = res.getPos();
client = res.getRedisClient();
if ("0".equals(pos)) {
client = null;
}
return new ScanIteration<byte[]>(Long.parseUnsignedLong(pos), res.getValues());
}
}.open();
}
@Override
public void rename(byte[] oldName, byte[] newName) {
if (isPipelined()) {
throw new InvalidDataAccessResourceUsageException("Clustered rename is not supported in a pipeline");
}
if (executorService.getConnectionManager().calcSlot(oldName) == executorService.getConnectionManager().calcSlot(newName)) {
super.rename(oldName, newName);
return;
}
final byte[] value = dump(oldName);
if (null != value) {
final Long sourceTtlInSeconds = ttl(oldName);
final long ttlInMilliseconds;
if (null != sourceTtlInSeconds && sourceTtlInSeconds > 0) {
ttlInMilliseconds = sourceTtlInSeconds * 1000;
} else {
ttlInMilliseconds = 0;View on GitHub (pinned to 91188987c2)
Solutions
- Exclude rename/renameNX from pipelined blocks: close the pipeline, perform the rename, then continue batching
- If source and destination are known same-slot (e.g. hash tags like {user:1}:a -> {user:1}:b), call the underlying single-command rename outside the pipeline — it is then a single RENAME
- Design keys with matching hash tags so renames stay single-slot and atomic
Example fix
// before connection.openPipeline(); connection.rename(oldKey, newKey); // throws connection.closePipeline(); // after connection.closePipeline(); connection.rename(oldKey, newKey); connection.openPipeline(); // resume batching other commands
Defensive patterns
Strategy: validation
Validate before calling
// Guard before pipelining anything that may rename:
if (connection.isPipelined()) {
connection.closePipeline(); // or use a separate connection for the rename
}
connection.rename(oldKey, newKey); Try / catch
try {
connection.rename(oldKey, newName);
} catch (InvalidDataAccessResourceUsageException e) {
// rename inside pipeline: close pipeline, retry outside, reopen if needed
connection.closePipeline();
connection.rename(oldKey, newName);
} Prevention
- Exclude rename/renameNX from pipelined batches by design
- Use hash tags ({tag}:key) so related keys share a slot and rename stays atomic
- Audit generic DAO 'executePipelined everything' advice when moving to cluster mode
When it happens
Trigger: Calling connection.rename(oldName, newName) while isPipelined() is true (after openPipeline()). Same-slot renames would delegate to super.rename(), but the pipeline check runs first, so ANY rename in a pipeline throws, regardless of slot.
Common situations: Generic Spring Redis DAOs that wrap all mutations in executePipelined(); code ported from a non-cluster or Lettuce setup where pipelined rename worked; batch rename loops that were 'optimized' with pipelining when moving to cluster.
Related errors
- Clustered rename is not supported in a pipeline
- Unable to close JNDI context
- Clustered rename is not supported in a pipeline
- Clustered rename is not supported in a pipeline
- Clustered rename is not supported in a pipeline
AI-assisted analysis of redisson/redisson@91188987c2 (2026-08-14).
Data as JSON: /api/errors/ee7cac55ab7affbe.
Report an issue: GitHub.