elastic/elasticsearch · error · IllegalArgumentException
vector dimensions incompatible
Error message
vector dimensions incompatible
What it means
Thrown by squareDistanceBulk(byte[] q, byte[] v0, v1, v2, v3, int distancesOffset, float[] distances): bulk squared distance from one byte query to four byte candidates. The guard rejects when q.length differs from any of v0..v3.length. Note the message is plain 'vector dimensions incompatible' (no sizes embedded) — inspect lengths yourself to localize the offending candidate.
Source
Thrown at libs/simdvec/src/main/java/org/elasticsearch/simdvec/ESVectorUtil.java:294
}
return IMPL.squareDistance(a, b);
}
/** Returns the sum of squared differences of the two byte vectors over a sub-range. */
public static float squareDistance(byte[] a, byte[] b, int offset, int length) {
if (a.length != b.length) {
throw new IllegalArgumentException("vector dimensions incompatible: " + a.length + "!= " + b.length);
}
Objects.checkFromIndexSize(offset, length, a.length);
return IMPL.squareDistance(a, b, offset, length);
}
/**
* Bulk computation of square distances from a byte query vector to four byte candidate vectors.
*/
public static void squareDistanceBulk(byte[] q, byte[] v0, byte[] v1, byte[] v2, byte[] v3, int distancesOffset, float[] distances) {
if (q.length != v0.length || q.length != v1.length || q.length != v2.length || q.length != v3.length) {
throw new IllegalArgumentException("vector dimensions incompatible");
}
if (distances.length < 4) {
throw new IllegalArgumentException("distances array must have length >= 4, but was: " + distances.length);
}
if (distancesOffset < 0 || distancesOffset > distances.length - 4) {
throw new IllegalArgumentException("distancesOffset must be between 0 and distances.length - 4");
}
IMPL.squareDistanceBulk(q, 0, v0, v1, v2, v3, distancesOffset, distances, q.length);
}
/**
* Bulk computation of square distances from a sub-range of a byte query vector to four byte candidate vectors.
*/
public static void squareDistanceBulk(
byte[] q,
int qOffset,
int length,
byte[] v0,View on GitHub (pinned to db6a809a66)
Solutions
- Before calling, assert q.length == v0.length == v1.length == v2.length == v3.length and log which one diverges.
- When padding candidate slots in graph traversal, pad with copies of a correctly-sized zero vector, not empty arrays.
- Validate decoded candidate length against the segment's quantized dims at read time.
Example fix
// before
ESVectorUtil.squareDistanceBulk(q, v0, v1, v2, v3, off, dist); // v2 wrong size
// after
for (byte[] v : new byte[][]{v0, v1, v2, v3}) {
if (v.length != q.length) throw new IllegalArgumentException(
"candidate length " + v.length + " != query " + q.length);
}
ESVectorUtil.squareDistanceBulk(q, v0, v1, v2, v3, off, dist); Defensive patterns
Strategy: validation
Validate before calling
int n = q.length;
if (v0.length!=n || v1.length!=n || v2.length!=n || v3.length!=n) {
throw new IllegalArgumentException("squareDistanceBulk candidate/query length mismatch: q=" + n
+ " v0=" + v0.length + " v1=" + v1.length + " v2=" + v2.length + " v3=" + v3.length);
}
ESVectorUtil.squareDistanceBulk(q, v0, v1, v2, v3, distancesOffset, distances); Try / catch
try {
ESVectorUtil.squareDistanceBulk(q, v0, v1, v2, v3, off, dist);
} catch (IllegalArgumentException e) {
throw new QueryException("squareDistanceBulk bad args (dims or scratch)", e);
} Prevention
- Pad graph-traversal candidate slots with correctly-sized zero vectors, not empty arrays.
- Validate decoded candidate length against the segment's quantized dims at read time.
- Log the divergent candidate index when the precondition fails.
When it happens
Trigger: Calling squareDistanceBulk where one of the four candidate byte vectors (v0..v3) has a different length from the query. Typical during HNSW graph traversal when a neighbor vector was decoded with a stale/shorter buffer, or when fewer than four real candidates are padded with differently-sized placeholders.
Common situations: Graph traversal padding short candidate slots with zero-length or differently-sized buffers; mixed quantization tiers across segments; a candidate loaded from a corrupted/shorter BytesRef; cross-version segment with different quantized dims.
Related errors
- distances array must have length >= 4, but was: {}
- distancesOffset must be between 0 and distances.length - 4
- distances array must have length 4, but was: {}
- vector dimensions incompatible: {}!= {} x {}
- distancesOffset must be between have length 0 and distances.
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/16ca7117ebf5cefd.
Report an issue: GitHub.