{"record":{"id":"7cacfcda70f7e9ae","repo":"apache/druid","slug":"exception-pulling-item-from-cache-7cacfc","errorCode":null,"errorMessage":"Exception pulling item from cache","messagePattern":"Exception pulling item from cache","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"extensions-contrib/redis-cache/src/main/java/org/apache/druid/client/cache/AbstractRedisCache.java","lineNumber":73,"sourceCode":"  {\n    totalRequestCount.incrementAndGet();\n    try {\n      byte[] bytes = getFromRedis(key.toByteArray());\n      if (bytes == null) {\n        missCount.incrementAndGet();\n        return null;\n      } else {\n        hitCount.incrementAndGet();\n        return bytes;\n      }\n    }\n    catch (JedisException e) {\n      if (e.getMessage().contains(\"Read timed out\")) {\n        timeoutCount.incrementAndGet();\n      } else {\n        errorCount.incrementAndGet();\n      }\n      log.warn(e, \"Exception pulling item from cache\");\n      return null;\n    }\n  }\n\n  @Override\n  public void put(NamedKey key, byte[] value)\n  {\n    totalRequestCount.incrementAndGet();\n    try {\n      this.putToRedis(key.toByteArray(), value, this.expiration);\n    }\n    catch (JedisException e) {\n      errorCount.incrementAndGet();\n      log.warn(e, \"Exception pushing item to cache\");\n    }\n  }\n\n  @Override","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-contrib/redis-cache/src/main/java/org/apache/druid/client/cache/AbstractRedisCache.java#L55-L91","documentation":"AbstractRedisCache.get() catches JedisException when fetching a value from Redis and logs a warning instead of propagating it, returning null so callers treat it as a cache miss. The message is emitted for any Redis read failure; if the message contains 'Read timed out' the timeoutCount metric is incremented, otherwise errorCount is. This is deliberately non-fatal: a broken cache should degrade lookup performance, not fail queries.","triggerScenarios":"Calling cache.get(key) when the Redis server is unreachable, connection is reset, or the socket read exceeds the configured timeout.","commonSituations":"Redis host/port misconfigured; Redis restarted or crashed; network latency or firewall dropping connections; Redis undersized so reads exceed the configured timeout; cluster failover in progress.","solutions":["Check Redis connectivity from the Druid host (redis-cli ping) and fix host/port/password config under druid.cache type=redis","Increase the timeout setting in the redis cache config so slow reads do not time out","Check Redis server logs for restarts, maxmemory eviction, or failover events","Monitor timeoutCount/errorCount metrics; treat persistent nonzero errorCount as a config/connectivity problem","Ensure the query can tolerate cache misses (cache is always best-effort)"],"exampleFix":"// before: cache config with too-tight timeout\n{\"type\":\"redis\",\"timeout\":\"50\"}\n// after\n{\"type\":\"redis\",\"timeout\":\"2000\"}","handlingStrategy":"fallback","validationCode":"// pre-check Redis reachability before relying on cached values\ntry (Jedis j = new Jedis(host, port, 2000)) { j.ping(); }","typeGuard":null,"tryCatchPattern":"// get() already swallows failures; treat null as miss\nbyte[] val = cache.get(key);\nif (val == null) { /* recompute from deep storage */ }","preventionTips":["Right-size the Redis timeout config","Monitor timeoutCount/errorCount metrics","Deploy Redis in the same datacenter/network as Druid","Alert on Redis restarts and maxmemory evictions"],"tags":["redis","cache","network","timeout"],"backgroundTag":"request-timeout","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}