redis/jedis · error · JedisConnectionException

Initialization failed due to initialization policy

Error message

Initialization failed due to initialization policy: ${ctx}

What it means

MultiDbConnectionProvider (multi-database failover client) evaluates the configured InitializationPolicy against the current health statuses of all configured Redis databases as soon as the client is built. If the very first evaluation returns Decision.FAIL, it throws JedisConnectionException. This means the initial state of your databases already violates the policy you configured (e.g. a policy requiring at least one healthy database while every endpoint is unhealthy), so the client refuses to finish initialization.

Solutions

  1. Fix the connection details (host, port, user, password, TLS) in MultiDbConfig for the failing endpoints so health checks pass.
  2. Verify each configured Redis endpoint is reachable (redis-cli -h <host> -p <port> PING) before constructing the client.
  3. Review the chosen InitializationPolicy: relax its thresholds or switch to a policy that tolerates the current number of unhealthy databases.
  4. Inspect the exception message's ConnectionInitializationContext toString, which lists per-endpoint health statuses, to see exactly which database is violating the policy.

Example fix

// before
MultiDbClient client = MultiDbClient.builder()
    .multiDbConfig(MultiDbConfig.builder()
        .database(a(context, "db1", 1.0f))
        .database(a(context, "db2", 0.5f))
        .initializationPolicy(InitializationPolicy.ALL_ACTIVE) // fails if ANY db is down
        .build())
    .build();
// after
MultiDbClient client = MultiDbClient.builder()
    .multiDbConfig(MultiDbConfig.builder()
        .database(a(context, "db1", 1.0f))
        .database(a(context, "db2", 0.5f))
        .initializationPolicy(InitializationPolicy.MAJORITY) // tolerant policy
        .build())
    .build();
Defensive patterns

Strategy: validation

Validate before calling

// Verify all configured endpoints answer PING before building the client
for (MultiDbConfig.DatabaseConfig db : config.getDatabases()) {
  try (Jedis probe = new Jedis(db.getEndpoint().getHost(), db.getEndpoint().getPort())) {
    if (!"PONG".equals(probe.ping())) throw new IllegalStateException(db + " not healthy");
  }
}

Try / catch

try {
  client = MultiDbClient.builder().multiDbConfig(cfg).build();
} catch (JedisConnectionException e) {
  log.error("Multi-db init policy failed: {}", e.getMessage());
  // fix config/environment, then retry with backoff
}

Prevention

When it happens

Trigger: Building a MultiDbClient/using MultiDbConnectionProvider where ConnectionInitializationContext.conformsTo(initializationPolicy) returns FAIL on the immediate (pre-wait) evaluation — e.g. the policy's failure predicate is already satisfied by the current health snapshot: all endpoints report unhealthy, or a failover policy's minimum-health condition is violated before any health check has resolved.

Common situations: Wrong hosts/ports or credentials in MultiDbConfig so all health checks fail immediately; Redis servers down or firewalled at startup; a custom InitializationPolicy (or a built-in one like all-min-available) whose thresholds cannot be met by the configured databases; running the client against an unreachable network/VPC from the start.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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

Appendix: source

Thrown at src/main/java/redis/clients/jedis/mcf/MultiDbConnectionProvider.java:421

   * @param statusTracker the status tracker to use for waiting on health check results
   * @return the first healthy database found, ordered by weight (highest first)
   * @throws JedisConnectionException (or JedisValidationException in unlikely cases) if
   *           initialization fails according to the policy
   */
  @VisibleForTesting
  Database waitForInitializationPolicy(StatusTracker statusTracker) {
    InitializationPolicy policy = multiDbConfig.getInitializationPolicy();
    log.debug("Waiting for initialization policy {} to complete for {} configured databases",
      policy.getClass().getSimpleName(), databaseMap.size());

    // Evaluate immediately with the current statuses
    ConnectionInitializationContext ctx = new ConnectionInitializationContext(databaseMap,
        healthStatusManager);
    Decision decision = ctx.conformsTo(policy);
    log.debug("Initial policy evaluation: {} with context: {}", decision, ctx);

    if (decision == Decision.FAIL) {
      throw new JedisConnectionException(
          "Initialization failed due to initialization policy: " + ctx);
    }

    // Sort databases by weight in descending order
    List<Map.Entry<Endpoint, Database>> sortedDatabases = databaseMap.entrySet().stream()
        .sorted(Map.Entry.<Endpoint, Database> comparingByValue(
          Comparator.comparing(Database::getWeight).reversed()))
        .collect(Collectors.toList());

    // Check databases in weight order
    for (Map.Entry<Endpoint, Database> entry : sortedDatabases) {
      Endpoint endpoint = entry.getKey();
      Database database = entry.getValue();

      log.info("Evaluating database {} (weight: {})", endpoint, database.getWeight());

      // Check if health checks are enabled for this endpoint
      if (healthStatusManager.hasHealthCheck(endpoint)) {

View on GitHub (pinned to 6dac31d4c2)