elastic/elasticsearch · error · IllegalArgumentException
database [%s] is already being downloaded via configuration
Error message
database [%s] is already being downloaded via configuration [%s]
What it means
Thrown by TransportPutDatabaseConfigurationAction.validatePrerequisites when another database configuration with a DIFFERENT id but the SAME name already exists. The 'name' (e.g. 'GeoLite2-City') maps to a single underlying database file per provider; two configs downloading the same file would duplicate work and waste bandwidth, so the second PUT is rejected.
Source
Thrown at modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/direct/TransportPutDatabaseConfigurationAction.java:127
return newDatabase.equals(existingDatabase.database());
}
}
static void validatePrerequisites(ProjectId projectId, DatabaseConfiguration database, ClusterState state) {
// we need to verify that the database represents a unique file (name) among the various databases for this same provider
IngestGeoIpMetadata geoIpMeta = state.metadata().getProject(projectId).custom(IngestGeoIpMetadata.TYPE, IngestGeoIpMetadata.EMPTY);
Optional<DatabaseConfiguration> sameName = geoIpMeta.getDatabases()
.values()
.stream()
.map(DatabaseConfigurationMetadata::database)
// .filter(d -> d.type().equals(database.type())) // of the same type (right now the type is always just 'maxmind')
.filter(d -> d.id().equals(database.id()) == false) // and a different id
.filter(d -> d.name().equals(database.name())) // but has the same name!
.findFirst();
sameName.ifPresent(d -> {
throw new IllegalArgumentException(
Strings.format("database [%s] is already being downloaded via configuration [%s]", database.name(), d.id())
);
});
}
private record UpdateDatabaseConfigurationTask(
ProjectId projectId,
ActionListener<AcknowledgedResponse> listener,
DatabaseConfiguration database
) implements ClusterStateTaskListener {
ClusterState execute(ClusterState currentState) throws Exception {
final var project = currentState.metadata().getProject(projectId);
IngestGeoIpMetadata geoIpMeta = project.custom(IngestGeoIpMetadata.TYPE, IngestGeoIpMetadata.EMPTY);
String id = database.id();
final DatabaseConfigurationMetadata existingDatabase = geoIpMeta.getDatabases().get(id);
// double-check for no-op in the state update task, in case it was changed/reset in the meantimeView on GitHub (pinned to db6a809a66)
Solutions
- Reuse the existing configuration id: PUT _ingest/geoip/database/<existing-id> to update it in place.
- DELETE the old configuration first, then PUT the new id with the same name.
- Give the new configuration a different 'name' if you genuinely want two separate database files.
Example fix
// before: 'city-a' already exists with name 'GeoLite2-City'
PUT _ingest/geoip/database/city-b
{ "name": "GeoLite2-City", "maxmind": { "account_id": "999" } }
// after: update the existing id instead
PUT _ingest/geoip/database/city-a
{ "name": "GeoLite2-City", "maxmind": { "account_id": "999" } } Defensive patterns
Strategy: validation
Validate before calling
// Before PUT, ensure the name is not already used by another id
Map<String, DatabaseConfiguration> existing = client.geoipDatabases().all();
String newName = body.get("name");
boolean nameTaken = existing.entrySet().stream()
.anyMatch(e -> !e.getKey().equals(myId) && newName.equals(e.getValue().name()));
if (nameTaken) {
throw new IllegalStateException("name '" + newName + "' already used by another config id");
} Prevention
- Reuse the existing id to update a config rather than creating a new one with the same name.
- DELETE the old config before PUTting a new id that reuses the name.
- Treat 'name' as a unique file identifier per provider, not just a label.
When it happens
Trigger: PUT _ingest/geoip/database/<new-id> with a body whose 'name' equals the 'name' of an existing configuration that has a different id. For example, config 'city-a' has name 'GeoLite2-City'; PUT 'city-b' with name 'GeoLite2-City' fails.
Common situations: Renaming a config by creating a new id with the same name instead of updating the old one; duplicating a config to change account_id without changing the name; re-creating after a failed delete left the original in place.
Related errors
- invalid database configuration id [{}]: must not be null or
- invalid database configuration id [{}]: id doesn't match req
- Database {} is read only
- wildcard only supports a single value, please use comma-sepa
- Resource count must be between 1 and 4
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/8c3360177a079a63.
Report an issue: GitHub.