redis/jedis · error · IllegalArgumentException
Client-side caching is only supported with RESP3.
Error message
Client-side caching is only supported with RESP3.
What it means
Client-side caching (RedisPROTOCOL-dependent server-assisted invalidation) requires RESP3, because it relies on push messages. Constructing a UnifiedJedis-derived client with both a Cache configured and RESP2 protocol throws IllegalArgumentException immediately.
Solutions
- Set the protocol to RESP3 in the ClientConfig: clientConfig.protocol(RedisProtocol.RESP3).
- Ensure the Redis server is v6+ and speaks RESP3.
- If RESP2 is mandatory, remove the cache from the configuration.
Example fix
// before ClientConfig cfg = new ClientConfig().protocol(RedisProtocol.RESP2); RedisClient c = RedisClient.builder().clientConfig(cfg).cache(new CachedRedisClient.Cache()).build(); // after ClientConfig cfg = new ClientConfig().protocol(RedisProtocol.RESP3); RedisClient c = RedisClient.builder().clientConfig(cfg).cache(new Caches.cache()).build();
Defensive patterns
Strategy: validation
Validate before calling
if (cache != null && (protocol == null || protocol == RedisProtocol.RESP2)) {
throw new IllegalArgumentException("cache requires RESP3");
} Try / catch
try {
RedisClient c = RedisClient.builder().clientConfig(cfg).cache(cache).build();
} catch (IllegalArgumentException e) {
log.error("CSC requires RESP3: {}", e.getMessage());
} Prevention
- Always set protocol(RESP3) when enabling client-side caching
- Verify server supports RESP3 (Redis 6+)
- Don't pass a Cache with legacy RESP2 configs
When it happens
Trigger: new RedisClient(...)/builder with .cache(...) while protocol is RESP2 or defaulted to RESP2; e.g. clientConfig.protocol(RedisProtocol.RESP2) plus a Cache instance.
Common situations: Upgrading an old RESP2-based config to add client-side caching; copying a cache example without setting RESP3; protocol defaulting to RESP2 in legacy config code paths.
Related errors
- Client-side caching is only supported with RESP3.
- binary ft.search is not implemented with resp3.
- HELLO response is missing the protocol version field
- HostAndPort is required when no socketFactory is provided
- DIALECT=0 cannot be set.
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/6eeb15273765331b.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/UnifiedJedis.java:144
// RESP2 or RESP3 on the wire. Probe a connection to learn the actual value so the command
// objects parse replies with the correct decoder. If the probe fails or the connection has
// not yet negotiated, fall back to RESP2 — matching the wire default and preserving lazy
// construction semantics.
RedisProtocol resolvedProtocol = protocol;
if (resolvedProtocol == null && provider != null) {
try (Connection conn = provider.getConnection()) {
if (conn != null) {
resolvedProtocol = conn.getRedisProtocol();
}
} catch (JedisException ignored) {
}
}
if (resolvedProtocol == null) {
resolvedProtocol = RedisProtocol.RESP2;
}
if (cache != null && resolvedProtocol != RedisProtocol.RESP3) {
throw new IllegalArgumentException("Client-side caching is only supported with RESP3.");
}
this.commandObjects = newCommandObjects(resolvedProtocol);
applyCommandObjectsConfiguration(commandObjects, clientConfig);
this.cache = cache;
}
/**
* Factory hook for the {@link CommandObjects} instance held by this client. Subclasses (e.g.
* {@link JedisCluster}) override to return their specialized subtype. Called from the
* {@link UnifiedJedis} constructor — must not depend on subclass instance state.
*/
protected CommandObjects newCommandObjects(RedisProtocol protocol) {
return new CommandObjects(protocol);
}
/**
* Applies the {@code CommandObjects}-level knobs ({@code commandKeyArgumentPreProcessor},View on GitHub (pinned to 6dac31d4c2)