redis/jedis · error · JedisException
Client side caching is only supported with RESP3.
Error message
Client side caching is only supported with RESP3.
What it means
initializeClientSideCache enforces that the connection uses the RESP3 protocol before enabling client tracking, because CLIENT TRACKING invalidations are delivered via RESP3 push messages. If the negotiated/selected protocol is RESP2, a JedisException is thrown. RESP2 has no push-message channel, so client-side caching cannot work.
Solutions
- Set the protocol in your config: implement JedisClientConfig.getRedisProtocol() to return RedisProtocol.RESP3 (or 3).
- Verify the Redis server supports RESP3 (Redis >= 6.0) and the negotiated protocol is RESP3 before enabling client-side caching.
- If RESP2 is mandatory, do not use client-side caching; use a plain Connection and explicit key reads instead.
Example fix
// before
JedisClientConfig config = new JedisClientConfig() { /* getRedisProtocol() default -> RESP2 */ };
// after
JedisClientConfig config = new JedisClientConfig() {
@Override public RedisProtocol getRedisProtocol() { return RedisProtocol.RESP3; }
}; Defensive patterns
Strategy: validation
Validate before calling
JedisClientConfig cfg = ...;
if (cfg.getRedisProtocol() == null || cfg.getRedisProtocol() != RedisProtocol.RESP3) {
throw new IllegalArgumentException("Client-side caching requires RESP3: set getRedisProtocol() to RedisProtocol.RESP3");
} Try / catch
try {
CacheConnection conn = CacheConnection.builder(cache).clientConfig(cfg).build();
} catch (JedisException e) {
if (e.getMessage().contains("RESP3")) {
// switch config to RESP3 or fall back to a non-caching connection
} else throw e;
} Prevention
- Always override getRedisProtocol() to return RedisProtocol.RESP3 in the JedisClientConfig used for caching connections
- Confirm the target server supports RESP3 (Redis >= 6.0)
- Keep RESP2-only clients on plain connections, not CacheConnection
When it happens
Trigger: Building a CacheConnection (or calling initializeFromClientConfig) while the connection's protocol is RESP2 — e.g. JedisClientConfig.getRedisProtocol() returning 2 or the default protocol being RESP2; upgrading the csc wiring without also setting the protocol.
Common situations: Server is Redis < 6 (RESP2 only) or the user explicitly configured protocol 2 for compatibility; legacy configuration files carried over from pre-caching setups; middleware that hardcodes RESP2.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Client-side caching is only supported with RESP3.
- Client-side caching is only supported with RESP3.
- binary ft.search is not implemented with resp3.
- HELLO response is missing the protocol version field
- Blocking pub/sub operations are not supported on…
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/6dc3c36f5ba30fa4.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/csc/CacheConnection.java:149
}
// CACHE MISS !!
cache.getStats().miss();
T value = super.executeCommand(commandObject);
cacheEntry = new CacheEntry<>(cacheKey, value, this);
cache.set(cacheKey, cacheEntry);
// this line actually provides a deep copy of cached object instance
value = cacheEntry.getValue();
return value;
}
public Cache getCache() {
return cache;
}
private void initializeClientSideCache() {
if (getRedisProtocol() != RedisProtocol.RESP3) {
throw new JedisException("Client side caching is only supported with RESP3.");
}
Objects.requireNonNull(cache);
if (!cache.compatibilityMode()) {
RedisVersion current = new RedisVersion(version);
RedisVersion required = new RedisVersion(MIN_REDIS_VERSION);
if (!REDIS.equals(server) || current.compareTo(required) < 0) {
throw new JedisException(
String.format("Client side caching is only supported with 'Redis %s' or later.", MIN_REDIS_VERSION));
}
}
addPushConsumer(new PushInvalidateConsumer(cache));
sendCommand(Protocol.Command.CLIENT, "TRACKING", "ON");
String reply = getStatusCodeReply();
if (!"OK".equals(reply)) {
throw new JedisException("Could not enable client tracking. Reply: " + reply);
}
}
View on GitHub (pinned to 6dac31d4c2)