elastic/elasticsearch · error · IllegalArgumentException

distancesOffset must be between 0 and distances.length - 4

Error message

distancesOffset must be between 0 and distances.length - 4

What it means

Thrown by squareDistanceBulk (byte, offset variant) when distancesOffset is out of range: the method writes four consecutive floats starting at distancesOffset, so the offset must satisfy 0 <= distancesOffset <= distances.length - 4. Negative offsets and offsets too close to the end are both rejected. The message names the valid range.

Source

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

        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,
        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) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Clamp distancesOffset to [0, distances.length - 4] before each call.
  2. When the scratch cursor reaches the limit, flush and reset to 0 instead of advancing.
  3. Size the scratch array as a multiple of 4 plus headroom so stride math stays in range.

Example fix

// before
int off = cursor; // could exceed distances.length - 4
ESVectorUtil.squareDistanceBulk(q, v0, v1, v2, v3, off, dist);

// after
int maxOff = dist.length - 4;
if (cursor < 0 || cursor > maxOff) cursor = 0; // flush+reset policy
ESVectorUtil.squareDistanceBulk(q, v0, v1, v2, v3, cursor, dist);
Defensive patterns

Strategy: validation

Validate before calling

if (distancesOffset < 0 || distancesOffset > distances.length - 4) {
    throw new IllegalArgumentException("squareDistanceBulk distancesOffset out of range: " + distancesOffset
        + " for distances.length " + distances.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 offset", e);
}

Prevention

When it happens

Trigger: Passing a negative distancesOffset, or a positive offset that leaves fewer than 4 slots before the end of the distances array. Typical when a shared scratch array is advanced past its usable window during batched scoring.

Common situations: Batching multiple bulk calls into one scratch array and forgetting to leave 4 slots of headroom; cursor that increments by the wrong stride; underflow when distances.length is exactly 4 and offset is nonzero.

Related errors


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