elastic/elasticsearch · error · IllegalArgumentException

distances array must have length 4, but was: {}

Error message

distances array must have length 4, but was: {}

What it means

Thrown by the windowed overload squareDistanceBulk(q, qOffset, length, v0..v3, distances) when distances.length != 4. Unlike the sibling overload that accepts distances.length >= 4 with an explicit distancesOffset, THIS overload requires the output array to be EXACTLY length 4 because it always writes four consecutive results at index 0. Reusing a larger scratch buffer from the other overload will trip this.

Source

Thrown at libs/simdvec/src/main/java/org/elasticsearch/simdvec/ESVectorUtil.java:322

    /**
     * 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,
        byte[] v1,
        byte[] v2,
        byte[] v3,
        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);
        }
        Objects.checkFromIndexSize(qOffset, length, q.length);
        IMPL.squareDistanceBulk(q, qOffset, v0, v1, v2, v3, 0, distances, length);
    }

    /**
     * Bulk computation of dot product from a byte query vector to four byte candidate vectors.
     */
    public static void dotProductBulk(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");
        }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Allocate a dedicated float[4] for the windowed overload — do not share with the offset overload.
  2. If you need a larger reusable scratch, call the (q, v0..v3, distancesOffset, distances) overload instead and pass offset 0.
  3. Add an assertion at scorer construction that the supplied distances array is exactly length 4 for this code path.

Example fix

// before
float[] dist = sharedScratch; // length 8, used by the offset overload too
ESVectorUtil.squareDistanceBulk(q, qOff, len, v0, v1, v2, v3, dist); // IAE

// after
float[] dist4 = new float[4];
ESVectorUtil.squareDistanceBulk(q, qOff, len, v0, v1, v2, v3, dist4);
Defensive patterns

Strategy: validation

Validate before calling

if (distances.length != 4) {
    throw new IllegalArgumentException("windowed squareDistanceBulk requires distances.length == 4, got " + distances.length);
}
ESVectorUtil.squareDistanceBulk(q, qOffset, length, v0, v1, v2, v3, distances);

Try / catch

try {
    ESVectorUtil.squareDistanceBulk(q, qOff, len, v0, v1, v2, v3, dist);
} catch (IllegalArgumentException e) {
    throw new QueryException("windowed squareDistanceBulk distances length must be 4", e);
}

Prevention

When it happens

Trigger: Calling the windowed squareDistanceBulk with a distances array of any length other than 4 — including a larger scratch buffer intended for the offset-based overload, or a smaller single-result buffer.

Common situations: Sharing scratch buffers between the two squareDistanceBulk overloads; allocating dist from a pool whose default capacity is not exactly 4; refactoring between overloads without resizing the output array.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/220aa710e08b71c1. Report an issue: GitHub.