elastic/elasticsearch · error · IllegalArgumentException
vector dimensions incompatible: {}!= {} x {}
Error message
vector dimensions incompatible: {}!= {} x {} What it means
Thrown by ipByteBinByte(byte[] q, byte[] d): inner product of a byte query against a 'bin'-packed byte document used by ES93 binary quantization scoring. Each document byte encodes B_QUERY (=4) query bytes, so the contract is q.length == d.length * B_QUERY (B_QUERY is 4, defined in ESVectorUtilSupport). The message embeds the actual q.length, B_QUERY and d.length so you can see which side is wrong.
Source
Thrown at libs/simdvec/src/main/java/org/elasticsearch/simdvec/ESVectorUtil.java:362
/**
* Bulk computation of cosine similarity from a byte query vector to four byte candidate vectors.
*/
public static void cosineBulk(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.cosineBulk(q, v0, v1, v2, v3, distancesOffset, distances);
}
public static long ipByteBinByte(byte[] q, byte[] d) {
if (q.length != d.length * B_QUERY) {
throw new IllegalArgumentException("vector dimensions incompatible: " + q.length + "!= " + B_QUERY + " x " + d.length);
}
return IMPL.ipByteBinByte(q, d);
}
/**
* Compute the inner product of two vectors, where the query vector is a byte vector and the document vector is a bit vector.
* This will return the sum of the query vector values using the document vector as a mask.
* When comparing the bits with the bytes, they are done in "big endian" order. For example, if the byte vector
* is [1, 2, 3, 4, 5, 6, 7, 8] and the bit vector is [0b10000000], the inner product will be 1.0.
* @param q the query vector
* @param d the document vector
* @return the inner product of the two vectors
*/
public static int ipByteBit(byte[] q, byte[] d) {
if (q.length != d.length * Byte.SIZE) {
throw new IllegalArgumentException("vector dimensions incompatible: " + q.length + "!= " + Byte.SIZE + " x " + d.length);
}
return IMPL.ipByteBit(q, d);View on GitHub (pinned to db6a809a66)
Solutions
- Verify the ES93 contract: the document must be bin-packed (1 bit per dim) and the query must be the 4-byte-per-64-dims quantized form, so q.length == d.length * 4.
- Log q.length, d.length and d.length * 4 at the call site to localize which side drifted.
- Ensure the same ES93 quantizer is used at index and query time; do not mix ES93 bin documents with plain int8 query encoding.
- If you cannot guarantee the 4x relation, route to a different scorer (e.g. ipByteBit or dotProduct) that matches your actual encodings.
Example fix
// before
long ip = ESVectorUtil.ipByteBinByte(qBytes, docBytes); // q.length != d.length * 4
// after
final int B_QUERY = 4;
if (qBytes.length != docBytes.length * B_QUERY) {
throw new IllegalArgumentException("ipByteBinByte contract violated: q.length="
+ qBytes.length + " expected d.length*" + B_QUERY + "=" + (docBytes.length * B_QUERY));
}
long ip = ESVectorUtil.ipByteBinByte(qBytes, docBytes); Defensive patterns
Strategy: validation
Validate before calling
final int B_QUERY = 4; // org.elasticsearch.simdvec.internal.vectorization.ESVectorUtilSupport.B_QUERY
if (q.length != d.length * B_QUERY) {
throw new IllegalArgumentException("ipByteBinByte contract: q.length=" + q.length
+ " must equal d.length*B_QUERY=" + (d.length * B_QUERY));
}
long ip = ESVectorUtil.ipByteBinByte(q, d); Try / catch
try {
long ip = ESVectorUtil.ipByteBinByte(q, d);
} catch (IllegalArgumentException e) {
throw new QueryException("ipByteBinByte: query not 4-byte-per-pack relative to bin document", e);
} Prevention
- Use the ES93 quantizer consistently for both index and query so q.length == d.length * 4 holds.
- Do not route plain int8 documents or queries into the ES93 bin scorer; pick ipByteBit / dotProduct instead.
- Log q.length, d.length and d.length*4 at the call site to localize drift after reindex or encoder swaps.
When it happens
Trigger: Calling ipByteBinByte where the query byte length is not exactly 4 times the document byte length. Typical when the query vector was not 4-bit quantized to match the bin-packed document, or when the document was not bin-packed (e.g. a raw int8 vector was supplied instead of a binary-quantized one).
Common situations: ES93 binary quantization scorer wired to a non-binary document vector; query encoder changed (e.g. from ES93 to a plain int8 encoder) without re-routing the scorer; dimension configuration that doesn't satisfy discretize(dims,64) producing the expected packed length; stale segment from before a reindex.
Related errors
- vector dimensions incompatible
- 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: {}
- distancesOffset must be between have length 0 and distances.
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/3562d15dff172509.
Report an issue: GitHub.