elastic/elasticsearch · error · ResourceNotFoundException

Database configuration not found: {}

Error message

Database configuration not found: {}

What it means

Thrown as ResourceNotFoundException by TransportDeleteDatabaseConfigurationAction.masterOperation when the requested database id is not present in the project's IngestGeoIpMetadata cluster state. DELETE is idempotent-failing here: a missing id is an error, not a silent success.

Source

Thrown at modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/direct/TransportDeleteDatabaseConfigurationAction.java:98

        );
        this.deleteDatabaseConfigurationTaskQueue = clusterService.createTaskQueue(
            "delete-geoip-database-configuration-state-update",
            Priority.NORMAL,
            DELETE_TASK_EXECUTOR
        );
        this.projectResolver = projectResolver;
    }

    @Override
    protected void masterOperation(Task task, Request request, ClusterState state, ActionListener<AcknowledgedResponse> listener)
        throws Exception {
        final String id = request.getDatabaseId();
        final ProjectId projectId = projectResolver.getProjectId();
        final IngestGeoIpMetadata geoIpMeta = state.metadata()
            .getProject(projectId)
            .custom(IngestGeoIpMetadata.TYPE, IngestGeoIpMetadata.EMPTY);
        if (geoIpMeta.getDatabases().containsKey(id) == false) {
            throw new ResourceNotFoundException("Database configuration not found: {}", id);
        } else if (geoIpMeta.getDatabases().get(id).database().isReadOnly()) {
            throw new IllegalArgumentException("Database " + id + " is read only");
        }
        deleteDatabaseConfigurationTaskQueue.submitTask(
            Strings.format("delete-geoip-database-configuration-[%s]", id),
            new DeleteDatabaseConfigurationTask(projectId, listener, id),
            null
        );
    }

    private record DeleteDatabaseConfigurationTask(ProjectId projectId, ActionListener<AcknowledgedResponse> listener, String databaseId)
        implements
            ClusterStateTaskListener {

        ClusterState execute(ClusterState currentState) throws Exception {
            final var project = currentState.metadata().getProject(projectId);
            final IngestGeoIpMetadata geoIpMeta = project.custom(IngestGeoIpMetadata.TYPE, IngestGeoIpMetadata.EMPTY);

View on GitHub (pinned to db6a809a66)

Solutions

  1. Verify the id exists first with GET _ingest/geoip/database/<id> and copy the exact id.
  2. If the delete already completed, treat the 404 as success and stop retrying.
  3. Ensure the client targets the correct project if multiple projects are in use.

Example fix

// before
DELETE _ingest/geoip/database/typo-id

// after
DELETE _ingest/geoip/database/my-city-db   // (confirmed via GET first)
Defensive patterns

Strategy: try-catch

Validate before calling

// Optional pre-check (still race-prone; the 404 is authoritative)
boolean exists = client.geoipDatabases().get(id) != null; // pseudo
if (!exists) { /* nothing to delete */ }

Try / catch

// Treat 404 on delete as acceptable when double-deleting
try {
    client.deleteDatabaseConfig(id);
} catch (ResourceNotFoundException e) {
    // already gone - treat as success
}

Prevention

When it happens

Trigger: DELETE _ingest/geoip/database/<id> where <id> was never created, was already deleted, or belongs to a different project. The lookup goes through the project resolver, so cross-project deletes also miss.

Common situations: Retrying a delete after it already succeeded; deleting by an id from a stale config list; typos in the id; deleting in the wrong project/namespace; the database was a read-only Local/Web entry that cannot be deleted and was concurrently removed.

Related errors


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