NationalSecurityAgency/ghidra · error · ElasticException
Could not recover unique executable via id
Error message
Could not recover unique executable via id
What it means
Thrown in queryExecutableRecordById when the total hit count for a specific executable _id within an msearch sub-response is not exactly 1. Since _id is the Elasticsearch primary key, exactly one document must match; a count of 0 means the document was deleted, and a count greater than 1 indicates index-level corruption or replication inconsistency.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java:1136
buffer.append(exeId);
buffer.append("\" }}}}}\n");
count += 1;
if (!iter1.hasNext()) {
break;
}
}
JsonObject bulkobj = connection.executeBulk(path, buffer.toString());
JsonArray responses = (JsonArray) bulkobj.get("responses");
for (int i = 0; i < count; ++i) {
JsonObject subquery = (JsonObject) responses.get(i);
JsonElement hits = subquery.get("hits");
if (ElasticConnection.isNull(hits)) {
throw new ElasticException("Multi-search for exe records failed");
}
JsonObject totalRec = (JsonObject) ((JsonObject) hits).get("total");
long total = totalRec.get("value").getAsLong();
if (total != 1) {
throw new ElasticException("Could not recover unique executable via id");
}
}
for (int i = 0; i < count; ++i) {
JsonObject subquery = (JsonObject) responses.get(i);
JsonObject hits = (JsonObject) subquery.get("hits");
JsonArray hitsArray = (JsonArray) hits.get("hits");
hits = (JsonObject) hitsArray.get(0);
ExecutableRecord newExe = makeExecutableRecord(manager, hits);
RowKey rowKey = iter2.next();
manager.cacheExecutableByRow(newExe, rowKey);
}
}
/**
* Query for function documents based on their parent executable id.
* A "page" of results is selected by selecting a -start- document and a maximum number to return
* @param exeId is the executable id
* @param maxDocuments is the maximum number of functions to returnView on GitHub (pinned to d5f144c24d)
Solutions
- Avoid concurrent delete and query operations on the same repository; serialize these operations.
- Set number_of_replicas appropriately and wait for green cluster health before querying to minimize stale replica reads.
- Re-run the query after concurrent operations have settled.
- If persistent, investigate Elasticsearch replication and read-consistency settings (e.g., set ?preference=_primary).
Defensive patterns
Strategy: validation
Validate before calling
// Before querying executable records, verify the document still exists
JsonObject check = connection.executeStatement(ElasticConnection.GET,
"executable/_doc/" + exeId, "{}");
if (check.get("found") != null && !check.get("found").getAsBoolean()) {
// Skip this executable — it was deleted
return;
} Try / catch
try {
database.query(query);
} catch (ElasticException e) {
if (e.getMessage().contains("Could not recover unique executable via id")) {
// Concurrent deletion likely; skip or retry after operations settle
Msg.warn(this, "Executable record not found (possibly deleted concurrently): " + e.getMessage());
}
throw e;
} Prevention
- Serialize delete and query operations on the same repository to avoid race conditions.
- Set appropriate number_of_replicas and wait for green health before querying.
- Use preference=_primary in Elasticsearch queries to reduce stale replica reads.
When it happens
Trigger: After the hits null-check passes for a sub-response, totalRec.get("value").getAsLong() returns a value other than 1. This happens when the executable document no longer exists (deleted between id collection and the msearch) or when replica shards return inconsistent results.
Common situations: Concurrent deletion of the executable record by another process; Elasticsearch replica inconsistency causing stale reads; race condition during concurrent ingest/delete; read from a recovering shard that has not yet indexed the document.
Related errors
- No functions matching vectorid:
- {getType()}scripts cannot be used for context [{context.name
- Unknown script name {scriptSource}
- Mismatch in metaid
- meta document does not exist for id=
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/70f8ee4cac2bfbd5.
Report an issue: GitHub.