redis/jedis · warning

Health check timed out or failed for

Error message

Health check timed out or failed for %s.

What it means

This is a warning logged by HealthCheckImpl.healthCheck when a scheduled health probe for an endpoint did not complete within the strategy timeout (TimeoutException) or the underlying check threw (ExecutionException). The in-flight probe future is cancelled and a failed result is recorded against the probing policy, which can eventually mark the endpoint UNHEALTHY and drive circuit-breaker failover in the multi-db (mcf) layer. It is a library-internal health-monitoring signal, not thrown to caller code.

Solutions

  1. Verify the endpoint (host/port) is reachable from the client host (ping/telnet the Redis endpoint and the REST API endpoint).
  2. Increase the health check strategy timeout (e.g. LagAwareStrategy.Config timeout) so probes under lag/network jitter complete.
  3. Check the wrapped exception in the log to distinguish timeout vs ExecutionException; fix the root cause it reports (REST auth, TLS, DNS).
  4. If this recurs under load, reduce health check concurrency pressure or lengthen the interval between probes.

Example fix

// before
LagAwareStrategy.Config cfg = new LagAwareStrategy.Config(restEndpoint, credsSupplier); // default/short timeout
// after
LagAwareStrategy.Config cfg = new LagAwareStrategy.Config.Builder(restEndpoint, credsSupplier)
    .timeout(5000) // ms; allow slow REST-based probes to finish
    .interval(10000)
    .build();
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check endpoint reachability before relying on health-driven failover
boolean reachable = false;
try (java.net.Socket s = new java.net.Socket()) {
  s.connect(new java.net.InetSocketAddress(endpoint.getHost(), endpoint.getPort()), 3000);
  reachable = true;
} catch (java.io.IOException e) {
  log.warn("Endpoint {} unreachable before start", endpoint);
}

Try / catch

// Health checks run inside the library; guard application-level failover instead
try {
  jedis.get("key");
} catch (redis.clients.jedis.exceptions.JedisConnectionException e) {
  // provider will fail over on breaker open; retry with backoff
  Thread.sleep(200);
  jedis.get("key");
}

Prevention

When it happens

Trigger: A single health probe submitted to the worker pool via future.get(strategy.getTimeout(), TimeUnit.MILLISECONDS) exceeds the configured HealthCheckStrategy timeout, or the strategy's doHealthCheck(endpoint) throws (e.g. JedisException from LagAwareStrategy REST calls, connection refused to the Redis Enterprise REST API).

Common situations: Endpoint is down or network is degraded so the health check hangs; timeout configured too low for a lag-aware REST check; Redis Enterprise REST API unreachable or slow; worker pool saturated causing slow probe execution.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/464a8f5d1b99247e. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/mcf/HealthCheckImpl.java:181

    log.trace("Health check completed for {} with status {}", endpoint, newStatus);
    return newStatus;
  }

  private void healthCheck() {
    long me = System.currentTimeMillis();
    HealthStatus update = null;
    HealthProbeContext probeContext = new HealthProbeContext(strategy.getPolicy(),
        strategy.getNumProbes());

    while (!probeContext.isCompleted()) {
      Future<HealthStatus> future = workers.submit(this::doHealthCheck);
      try {
        update = future.get(strategy.getTimeout(), TimeUnit.MILLISECONDS);
        probeContext.record(update == HealthStatus.HEALTHY);
      } catch (TimeoutException | ExecutionException e) {
        future.cancel(true);
        if (log.isWarnEnabled()) {
          log.warn(String.format("Health check timed out or failed for %s.", endpoint), e);
        }
        probeContext.record(false);
      } catch (InterruptedException e) {// Health check thread was interrupted
        future.cancel(true);
        Thread.currentThread().interrupt(); // Restore interrupted status
        log.warn(String.format("Health check interrupted for %s.", endpoint), e);
        // thread interrupted, stop health check process
        return;
      }
      if (!probeContext.isCompleted()) {
        try {
          Thread.sleep(strategy.getDelayInBetweenProbes());
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt(); // Restore interrupted status
          log.warn(String.format("Health check interrupted while sleeping for %s.", endpoint), e);
          // thread interrupted, stop health check process
          return;
        }

View on GitHub (pinned to 6dac31d4c2)