redisson/redisson · error · CacheException
Unable to locate Redisson instance by name: ${jndiName}
Error message
Unable to locate Redisson instance by name: ${jndiName} What it means
RedissonConnection.scan() iterates master entries directly over raw connections, producing a live Cursor. Cursors require request/response round-trips per batch, so Redisson refuses to run SCAN while the connection is in MULTI queueing or pipeline mode, throwing UnsupportedOperationException from doScan.
Source
Thrown at redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/JndiRedissonRegionNativeFactory.java:53
private static final long serialVersionUID = -4814502675083325567L;
public static final String JNDI_NAME = CONFIG_PREFIX + "jndi_name";
@Override
protected RedissonClient createRedissonClient(Properties properties) {
String jndiName = ConfigurationHelper.getString(JNDI_NAME, properties);
if (jndiName == null) {
throw new CacheException(JNDI_NAME + " property not set");
}
Properties jndiProperties = JndiServiceImpl.extractJndiProperties(properties);
InitialContext context = null;
try {
context = new InitialContext(jndiProperties);
return (RedissonClient) context.lookup(jndiName);
} catch (NamingException e) {
throw new CacheException("Unable to locate Redisson instance by name: " + jndiName, e);
} finally {
if (context != null) {
try {
context.close();
} catch (NamingException e) {
throw new CacheException("Unable to close JNDI context", e);
}
}
}
}
@Override
public void stop() {
}
}
View on GitHub (pinned to 91188987c2)
Solutions
- Run scan outside any pipeline/transaction: use RedisTemplate.scan(options) or a raw connection cursor on a non-pipelined connection.
- Collect keys with SCAN first, then pipeline the follow-up operations on those keys.
- If a single blocking call is acceptable in pipeline mode, use conn.keys(pattern) instead of scan.
Example fix
// before
redisTemplate.executePipelined((RedisCallback<Object>) conn -> {
Cursor<byte[]> c = conn.scan(ScanOptions.scanOptions().match("sess:*").build());
c.forEachRemaining(k -> redisTemplate.delete(new String(k))); // throws inside pipeline
return null;
});
// after
try (Cursor<byte[]> c = redisTemplate.scan(ScanOptions.scanOptions().match("sess:*").build())) {
List<String> keys = c.stream().map(String::new).collect(Collectors.toList());
if (!keys.isEmpty()) redisTemplate.delete(keys);
} Defensive patterns
Strategy: validation
Validate before calling
if (conn.isPipelined() || conn.isQueueing()) {
throw new IllegalStateException("SCAN not allowed here; collect keys first, pipeline later");
}
try (Cursor<byte[]> c = conn.scan(options)) { ... } Try / catch
catch (UnsupportedOperationException e) where message contains "pipeline / transaction mode": move the scan to a fresh connection obtained outside executePipelined and re-run.
Prevention
- Standardize on RedisTemplate.scan(options) for key iteration and reserve executePipelined for sets of known keys.
- Never create cursors inside RedisCallback/SessionCallback bodies that run pipelined.
- Integration-test batch jobs in both plain and pipelined modes so pipeline/scan mixing is caught early.
When it happens
Trigger: Calling conn.scan(ScanOptions) inside RedisTemplate.executePipelined(...) or inside a multi()/exec() SessionCallback. The ScanCursor is lazily evaluated, so the exception surfaces when the cursor is first advanced or closed (inside the pipeline callback), not when scan() is called.
Common situations: Wrapping RedisTemplate.scan(cursor) in executePipelined hoping to batch results; calling scan within RedisTransactionalSessionCallback; frameworks that implicitly pipeline callbacks (e.g. some RedisTemplate operations inside executePipelined).
Related errors
- 'SSCAN' cannot be called in pipeline / transaction mode.
- Unable to locate Redisson instance by name: ${jndiName}
- 'SSCAN' cannot be called in pipeline / transaction mode.
- 'SSCAN' cannot be called in pipeline / transaction mode.
- 'SSCAN' cannot be called in pipeline / transaction mode.
AI-assisted analysis of redisson/redisson@91188987c2 (2026-08-14).
Data as JSON: /api/errors/946599ea3ab096fe.
Report an issue: GitHub.