redis/jedis · error · JedisConnectionException
No healthy database available after initialization policy…
Error message
No healthy database available after initialization policy succeeded.
What it means
selectBestAvailableDatabase is only called after the InitializationPolicy reported SUCCESS, yet when it scans databases in weight order it expects to find at least one healthy database. If every status check comes back unhealthy anyway (statuses changed between the policy evaluation and the selection, or no health check is configured and status is still unhealthy), this defensive JedisConnectionException is thrown. Per the source comment, it 'should not happen if policy succeeded', indicating a race or inconsistent health state.
Solutions
- Retry client construction; if transient, a healthy state at build time avoids the race.
- If using a custom InitializationPolicy, ensure its SUCCESS decision actually requires at least one healthy database.
- Investigate why all endpoints turned unhealthy in that instant (check health-check logs and Redis server availability).
- Tune health check thresholds so borderline/flapping endpoints are not toggling status during startup.
Example fix
// before — custom policy can report SUCCESS with zero healthy dbs
public Decision evaluate(ctx) {
return ctx.getTotalCount() > 0 ? Decision.SUCCESS : Decision.FAIL;
}
// after — require at least one healthy database
public Decision evaluate(ctx) {
return ctx.getHealthyCount() > 0 ? Decision.SUCCESS : Decision.FAIL;
} Defensive patterns
Strategy: retry
Try / catch
try {
client = MultiDbClient.builder().multiDbConfig(cfg).build();
} catch (JedisConnectionException e) {
if (e.getMessage().contains("No healthy database available after initialization")) {
// transient race — rebuild after a short delay
Thread.sleep(1000);
client = MultiDbClient.builder().multiDbConfig(cfg).build();
}
} Prevention
- If implementing a custom InitializationPolicy, make SUCCESS require getHealthyCount() > 0.
- Avoid flapping health thresholds that let statuses flip during startup.
- Report persistent occurrences as a bug — the library marks this path as unreachable when the policy succeeds correctly.
- Keep at least one endpoint free of aggressive health probes so it defaults to HEALTHY.
When it happens
Trigger: waitForInitializationPolicy gets Decision.SUCCESS from the policy, then selectBestAvailableDatabase iterates sortedDatabases and healthStatusManager.getHealthStatus(endpoint) returns unhealthy for every endpoint — a race where health statuses flip to unhealthy between policy evaluation and database selection, or a policy that succeeds despite no healthy status (e.g. a custom policy).
Common situations: All databases become unhealthy in the window between policy evaluation and selection (mass outage starting exactly at startup); a custom InitializationPolicy whose SUCCESS logic does not require any healthy database; flapping health checks that pass at evaluation time and fail moments later.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Initialization failed due to initialization policy
- Initialization failed due to initialization policy
- All configured databases are unhealthy. Cannot initialize…
- failed to connect. Please check configuration and try again.
- Attempting to write to a broken connection.
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/3ffeef734db208d1.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/mcf/MultiDbConnectionProvider.java:502
// Check if health checks are enabled for this endpoint
if (healthStatusManager.hasHealthCheck(endpoint)) {
status = healthStatusManager.getHealthStatus(endpoint);
} else {
// No health check configured - assume healthy
log.info("No health check configured for database {}, defaulting to HEALTHY", endpoint);
status = HealthStatus.HEALTHY;
}
if (status.isHealthy()) {
log.info("Found healthy database: {} (weight: {})", endpoint, database.getWeight());
return database;
} else {
log.info("Database {} is unhealthy, trying next database", endpoint);
}
}
// No healthy database found (should not happen if policy succeeded)
throw new JedisConnectionException(
"No healthy database available after initialization policy succeeded.");
}
/**
* Periodic failback checker - runs at configured intervals to check for failback opportunities
*/
@VisibleForTesting
void periodicFailbackCheck() {
try {
// Find the best candidate database for failback
Map.Entry<Endpoint, Database> bestCandidate = null;
float bestWeight = activeDatabase.getWeight();
for (Map.Entry<Endpoint, Database> entry : databaseMap.entrySet()) {
Database database = entry.getValue();
// Skip if this is already the active database
if (database == activeDatabase) {View on GitHub (pinned to 6dac31d4c2)