redis/jedis · error · JedisValidationException
Endpoint already exists in the provider
Error message
Endpoint ${config.getEndpoint()} already exists in the provider What it means
Internal addDatabaseInternal() re-checks endpoint uniqueness before registering a database: if the endpoint is already in databaseMap it throws a JedisValidationException. This is the lock-protected internal path used by add(), so it surfaces the same duplicate-endpoint rule that add() checks, plus is the direct guard for constructor-time registrations.
Solutions
- Deduplicate endpoints in MultiDbConfig before constructing the provider.
- Serialize add() calls or check an application-level endpoint set before calling add().
- Catch JedisValidationException for 'already exists' and treat it as idempotent success if appropriate.
Example fix
// before new MultiDbConnectionProvider(MultiDbConfig.builder(ep1).addDatabase(ep1Dup)...build(), cache); // after Set<Endpoint> seen = new HashSet<>(); MultiDbConfig.Builder b = MultiDbConfig.builder(ep1); seen.add(ep1); if (seen.add(ep1Dup)) b.addDatabase(ep1Dup); // skip duplicates
Defensive patterns
Strategy: validation
Validate before calling
Set<Endpoint> seen = new HashSet<>();
for (DatabaseConfig cfg : configs) {
if (!seen.add(cfg.getEndpoint())) continue; // skip duplicates
provider.add(cfg);
} Try / catch
try {
provider.add(cfg);
} catch (JedisValidationException e) {
if (e.getMessage().contains("already exists")) {
// concurrent duplicate add; ignore
} else {
throw e;
}
} Prevention
- Deduplicate endpoint lists before provider construction and dynamic adds.
- Synchronize add() calls in concurrent code paths.
- Write tests covering duplicate endpoints in configuration.
When it happens
Trigger: Adding a DatabaseConfig whose endpoint already exists — via provider.add(config) racing another add, or during provider construction when initial config lists a duplicate endpoint.
Common situations: Concurrent add() calls from multiple threads adding the same endpoint; configuration files listing the same host:port more than once; re-adding an endpoint after a failed removal.
Related errors
- Endpoint already exists in the provider
- Endpoint does not exist.
- MultiDbConfig must not be NULL for MultiDbConnectionProvider
- DatabaseConfig must not be null
- Endpoint must not be null
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/5002eb611f26979e.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/mcf/MultiDbConnectionProvider.java:323
if (databaseToRemove != null) {
databaseToRemove.setDisabled(true);
databaseToRemove.close();
}
} finally {
activeDatabaseChangeLock.unlock();
}
if (notificationData != null) {
onDatabaseSwitch(SwitchReason.FORCED, notificationData.getKey(), notificationData.getValue());
}
}
/**
* Internal method to add a database configuration. This method is not thread-safe and should be
* called within appropriate locks.
*/
private void addDatabaseInternal(MultiDbConfig multiDbConfig, DatabaseConfig config) {
if (databaseMap.containsKey(config.getEndpoint())) {
throw new JedisValidationException(
"Endpoint " + config.getEndpoint() + " already exists in the provider");
}
String databaseId = "database:" + config.getEndpoint();
Retry retry = RetryRegistry.of(retryConfig).retry(databaseId);
Retry.EventPublisher retryPublisher = retry.getEventPublisher();
retryPublisher.onRetry(event -> log.warn(String.valueOf(event)));
retryPublisher.onError(event -> log.error(String.valueOf(event)));
CircuitBreaker circuitBreaker = CircuitBreakerRegistry.of(circuitBreakerConfig)
.circuitBreaker(databaseId);
CircuitBreaker.EventPublisher circuitBreakerEventPublisher = circuitBreaker.getEventPublisher();
circuitBreakerEventPublisher.onCallNotPermitted(event -> log.error(String.valueOf(event)));
circuitBreakerEventPublisher.onError(event -> log.error(String.valueOf(event)));
circuitBreakerEventPublisher.onFailureRateExceeded(event -> log.error(String.valueOf(event)));View on GitHub (pinned to 6dac31d4c2)