{"record":{"id":"396b4c44f9c1bd54","repo":"redis/jedis","slug":"timeout-while-waiting-for-health-check-result","errorCode":null,"errorMessage":"Timeout while waiting for health check result","messagePattern":"Timeout while waiting for health check result","errorType":"validation","errorClass":"JedisValidationException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/mcf/StatusTracker.java","lineNumber":68,"sourceCode":"      }\n    };\n\n    // Register the temporary listener\n    healthStatusManager.registerListener(endpoint, tempListener);\n\n    try {\n      // Double-check status after registering listener (race condition protection)\n      currentStatus = healthStatusManager.getHealthStatus(endpoint);\n      if (currentStatus != HealthStatus.UNKNOWN) {\n        return currentStatus;\n      }\n\n      // Wait for the health status change event\n      // just for safety to not block indefinitely\n      boolean completed = latch.await(healthStatusManager.getMaxWaitFor(endpoint),\n        TimeUnit.MILLISECONDS);\n      if (!completed) {\n        throw new JedisValidationException(\"Timeout while waiting for health check result\");\n      }\n      return resultStatus.get();\n\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new JedisConnectionException(\"Interrupted while waiting for health check result\", e);\n    } finally {\n      // Clean up: unregister the temporary listener\n      healthStatusManager.unregisterListener(endpoint, tempListener);\n    }\n  }\n}\n","sourceCodeStart":50,"sourceCodeEnd":81,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/mcf/StatusTracker.java#L50-L81","documentation":"StatusTracker.waitForHealthStatus blocks on a CountDownLatch waiting for the health status manager to report a state change for a MultiDb failover endpoint. If the latch does not count down within healthStatusManager.getMaxWaitFor(endpoint) milliseconds, the tracker gives up and throws JedisValidationException so callers never block indefinitely on an unreachable or unhealthy endpoint.","triggerScenarios":"Calling waitForHealthStatus (typically via waitForInitializationPolicy during MultiDbClient/RedisClient failover-aware initialization) when the endpoint's health check never completes within the configured max wait window, e.g. the Redis node is unreachable, the health check listener never fires, or the max-wait timeout is set too low for slow networks or slow Redis startup.","commonSituations":"Configuring a multi-db client against a dead or firewalled Redis endpoint; setting the per-endpoint max wait (healthCheckMaxWait / getMaxWaitFor source) to a value smaller than actual connection establishment time; Redis starting slower than the client during orchestrated failovers or container startup races.","solutions":["Verify the target endpoint is reachable and healthy (redis-cli -h host -p port PING) before client initialization.","Increase the configured max wait for the endpoint so slow health checks can complete.","Check that the health check probe configuration (interval, timeout, endpoint address) matches the actual Redis instance.","Inspect network/firewall/security-group rules between client and endpoint if the latch times out consistently.","Catch JedisValidationException around initialization and fall back to another endpoint in the multi-db list."],"exampleFix":"// before\nMultiDbClient client = MultiDbClient.builder()\n    .multiDbEndpoints(endpoints) // endpoint health check max wait too small\n    .build();\n// after\nMultiDbClient client = MultiDbClient.builder()\n    .multiDbEndpoints(endpoints)\n    .connectionTimeout(5, TimeUnit.SECONDS) // give health checks room to complete\n    .healthCheckMaxWait(30, TimeUnit.SECONDS)\n    .build();","handlingStrategy":"validation","validationCode":"if (!isEndpointReachable(endpoint)) throw new IllegalStateException(\"skip init: endpoint down \" + endpoint);\n// and ensure configured maxWait >= worst-case connect+health-check time","typeGuard":null,"tryCatchPattern":"try {\n  tracker.waitForHealthStatus(endpoint);\n} catch (JedisValidationException e) {\n  log.warn(\"health check timed out for {}\", endpoint, e);\n  failoverToAlternateEndpoint();\n}","preventionTips":["Ping endpoints with redis-cli before configuring them as databases.","Set health check max wait generously above network worst case.","Monitor health check events to catch flapping endpoints early."],"tags":["health-check","timeout","multi-db","failover"],"backgroundTag":"request-timeout","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"}