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
- Verify the id exists first with GET _ingest/geoip/database/<id> and copy the exact id.
- If the delete already completed, treat the 404 as success and stop retrying.
- 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
- GET the id first to confirm it exists before DELETE.
- Make delete-retry logic tolerant of 404 (treat as already-deleted).
- Copy the exact id from GET output rather than retyping.
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
- data streams {} not found
- invalid database configuration id [{}]: must not be null or
- invalid database configuration id [{}]: id doesn't match req
- Database {} is read only
- Database {} is read only
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/46818bcc2449376c.
Report an issue: GitHub.