{"record":{"id":"6dc3c36f5ba30fa4","repo":"redis/jedis","slug":"client-side-caching-is-only-supported-with-resp3-6dc3c3","errorCode":null,"errorMessage":"Client side caching is only supported with RESP3.","messagePattern":"Client side caching is only supported with RESP3\\.","errorType":"exception","errorClass":"JedisException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/csc/CacheConnection.java","lineNumber":149,"sourceCode":"    }\n\n    // CACHE MISS !!\n    cache.getStats().miss();\n    T value = super.executeCommand(commandObject);\n    cacheEntry = new CacheEntry<>(cacheKey, value, this);\n    cache.set(cacheKey, cacheEntry);\n    // this line actually provides a deep copy of cached object instance\n    value = cacheEntry.getValue();\n    return value;\n  }\n\n  public Cache getCache() {\n    return cache;\n  }\n\n  private void initializeClientSideCache() {\n    if (getRedisProtocol() != RedisProtocol.RESP3) {\n      throw new JedisException(\"Client side caching is only supported with RESP3.\");\n    }\n    Objects.requireNonNull(cache);\n    if (!cache.compatibilityMode()) {\n      RedisVersion current = new RedisVersion(version);\n      RedisVersion required = new RedisVersion(MIN_REDIS_VERSION);\n      if (!REDIS.equals(server) || current.compareTo(required) < 0) {\n        throw new JedisException(\n          String.format(\"Client side caching is only supported with 'Redis %s' or later.\", MIN_REDIS_VERSION));\n      }\n    }\n    addPushConsumer(new PushInvalidateConsumer(cache));\n    sendCommand(Protocol.Command.CLIENT, \"TRACKING\", \"ON\");\n    String reply = getStatusCodeReply();\n    if (!\"OK\".equals(reply)) {\n      throw new JedisException(\"Could not enable client tracking. Reply: \" + reply);\n    }\n  }\n","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/csc/CacheConnection.java#L131-L167","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nJedisClientConfig config = new JedisClientConfig() { /* getRedisProtocol() default -> RESP2 */ };\n// after\nJedisClientConfig config = new JedisClientConfig() {\n  @Override public RedisProtocol getRedisProtocol() { return RedisProtocol.RESP3; }\n};","handlingStrategy":"validation","validationCode":"JedisClientConfig cfg = ...;\nif (cfg.getRedisProtocol() == null || cfg.getRedisProtocol() != RedisProtocol.RESP3) {\n  throw new IllegalArgumentException(\"Client-side caching requires RESP3: set getRedisProtocol() to RedisProtocol.RESP3\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  CacheConnection conn = CacheConnection.builder(cache).clientConfig(cfg).build();\n} catch (JedisException e) {\n  if (e.getMessage().contains(\"RESP3\")) {\n    // switch config to RESP3 or fall back to a non-caching connection\n  } else throw e;\n}","preventionTips":["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"],"tags":["client-side-caching","resp3","protocol-mismatch"],"backgroundTag":"invalid-config-value","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}