t8y2/dbx · error · java.lang.IllegalArgumentException
The default MongoDB _id_ index cannot be dropped
Error message
The default MongoDB _id_ index cannot be dropped
What it means
MongoDB's default _id_ index is created automatically for every collection and cannot be dropped at the server level. The agent rejects requests that name it — either as the literal name "_id_" or as an equivalent key-pattern specification — before contacting the server.
Source
Thrown at agents/drivers/mongodb/src/main/java/com/dbx/agent/mongodb/MongoAgent.java:1382
static Object parseDropIndexesValue(String indexesJson, boolean single) {
if (indexesJson == null || indexesJson.isBlank()) {
if (single) {
throw new IllegalArgumentException("dropIndex requires a string index name or JSON document");
}
return "*";
}
JsonElement value = JsonParser.parseString(indexesJson);
if (value.isJsonPrimitive() && value.getAsJsonPrimitive().isString()) {
String name = value.getAsString();
if (name.isBlank()) {
throw new IllegalArgumentException("Index name is required");
}
if (single && "*".equals(name)) {
throw new IllegalArgumentException("dropIndex does not accept \"*\"; use dropIndexes() or dropIndexes(\"*\") instead");
}
if (DEFAULT_ID_INDEX_NAME.equals(name)) {
throw new IllegalArgumentException("The default MongoDB _id_ index cannot be dropped");
}
return name;
}
if (value.isJsonObject()) {
JsonObject object = value.getAsJsonObject();
if (object.size() == 0) {
throw new IllegalArgumentException("Index specification is required");
}
Document specification = Document.parse(indexesJson);
if (isDefaultIdIndexSpecification(specification)) {
throw new IllegalArgumentException("The default MongoDB _id_ index cannot be dropped");
}
return specification;
}
if (value.isJsonArray()) {
if (single) {
throw new IllegalArgumentException("dropIndex only accepts a string index name or JSON document; arrays are not supported");
}View on GitHub (pinned to c0390bff16)
Solutions
- Skip indexes named "_id_" (or key {"_id": 1}) in your drop loop
- Only drop secondary indexes you explicitly created
- To change _id behavior, redesign the schema rather than dropping the index
Example fix
// before
for (Document idx : collection.listIndexes()) {
drop(idx.getString("name")); // includes "_id_"
}
// after
for (Document idx : collection.listIndexes()) {
String name = idx.getString("name");
if (!"_id_".equals(name)) {
drop(name);
}
} Defensive patterns
Strategy: validation
Validate before calling
if ("_id_".equals(indexName)) {
return; // skip: _id index is mandatory in MongoDB
} Type guard
boolean isDroppableIndex(Document indexInfo) {
String name = indexInfo.getString("name");
return name != null && !"_id_".equals(name);
} Try / catch
try {
agent.execute("dropIndex", params);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("_id_ index cannot be dropped")) {
log.info("Skipped mandatory _id index");
} else { throw e; }
} Prevention
- Skip '_id_' when iterating getIndexes()/listIndexes output
- Check key patterns containing only {'_id': 1} as well as names
- Document that _id indexes are immutable in your maintenance scripts
When it happens
Trigger: Calling dropIndex or dropIndexes with indexes="_id_", or with a JSON document equivalent to the _id index (e.g. {"_id": 1}) that matches isDefaultIdIndexSpecification.
Common situations: Iterating db.collection.getIndexes() output and dropping every returned index including _id_; trying to rebuild/replace the _id index; cleanup scripts that don't special-case _id_.
Related errors
- dropIndex requires a string index name or JSON document
- Index name is required
- dropIndex does not accept "*"; use dropIndexes() or dropInde
- Index specification is required
- MongoDB aggregate option ${key} must be a non-negative integ
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/806481db7c6295c1.
Report an issue: GitHub.