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 meantime

View on GitHub (pinned to db6a809a66)

Solutions

  1. Reuse the existing configuration id: PUT _ingest/geoip/database/<existing-id> to update it in place.
  2. DELETE the old configuration first, then PUT the new id with the same name.
  3. 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

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


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/8c3360177a079a63. Report an issue: GitHub.