NationalSecurityAgency/ghidra · error · ElasticException

Mismatch in decrementVectorCounters

Error message

Mismatch in decrementVectorCounters

What it means

Thrown in decrementVectorCounters when the _id decoded from a bulk update response item does not match the expected vector id from the iterator. Elasticsearch's bulk API guarantees responses are returned in the same order as requests; a mismatch indicates a protocol contract violation, response body corruption, or a desynchronization between the two parallel iterators (iter1 for building requests, iter2 for matching responses).

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java:1828

			buffer.append("\"_id\": \"");
			Base64Lite.encodeLongBase64(buffer, entry.id);
			buffer.append("\", \"retry_on_conflict\": 5 } }\n");
			buffer.append(
				"{ \"script\": { \"inline\": \"if ((ctx._source.count -= params.count) <=0) { ctx.op = \\\"delete\\\" }\", ");
			buffer.append("\"params\": { \"count\": ").append(entry.count).append("} } }\n");
		}
		JsonObject resp = connection.executeBulk("/_bulk", buffer.toString());
		JsonArray items = (JsonArray) resp.get("items");
		for (int i = 0; i < maxVectors; ++i) {
			if (!iter2.hasNext()) {
				break;
			}
			IdHistogram entry = iter2.next();
			JsonObject item = (JsonObject) items.get(i);
			JsonObject update = (JsonObject) item.get("update");
			long id = Base64Lite.decodeLongBase64(update.get("_id").getAsString());
			if (id != entry.id) {
				throw new ElasticException("Mismatch in decrementVectorCounters");
			}
			if ("deleted".equals(ElasticConnection.convertToString(update.get("result")))) {
				deleteList.add(entry);				// Mark this vector for full deletion
			}
		}
	}

	/**
	 * Delete vector documents in bulk. This assumes multiplicity counts in the "meta" documents
	 * have already been checked, and these vectors are scheduled for full document deletion.
	 * Vectors are presented as an iterator to IdHistograms. One bulk deletion request is
	 * submitted containing vectors up to a given maximum number. The iterator is advanced by
	 * the number submitted
	 * @param iter is an iterator over records containing the id's to delete
	 * @param maxVectors is the maximum number to delete for this window
	 * @throws ElasticException for communication problems with the server
	 */
	private void deleteRawVectors(Iterator<IdHistogram> iter, int maxVectors)

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Report as a bug — this guard should never fire with a compliant Elasticsearch server; investigate proxy or load-balancer interference with bulk NDJSON responses.
  2. Verify that the two iterators (iter1, iter2) passed to decrementVectorCounters point to the same underlying list and are at the same position.
  3. Check for any HTTP intermediary (reverse proxy, API gateway) that might buffer or reorder bulk responses.
  4. Confirm the Elasticsearch server version adheres to the standard bulk response ordering contract.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    database.query(query);
} catch (ElasticException e) {
    if (e.getMessage().contains("Mismatch in decrementVectorCounters")) {
        // Should never occur — indicates protocol violation or proxy interference
        Msg.error(this, "Bulk response order mismatch — check proxy/load-balancer: " + e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: During executable deletion, decrementVectorCounters sends a bulk update to repository_meta with retry_on_conflict=5, then iterates the response items alongside iter2. Base64Lite.decodeLongBase64(update.get("_id").getAsString()) for item i is compared against entry.id from iter2; any difference triggers the exception.

Common situations: Should never occur under normal operation. If seen, it points to: a proxy or load balancer reordering or corrupting bulk response items; a bug in how iter1 and iter2 are managed by the caller; an Elasticsearch bulk API contract violation in a non-standard server fork.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/e9df2612482da68b. Report an issue: GitHub.