elastic/elasticsearch · error · IllegalArgumentException
Unsupported bitsPerDim: {}
Error message
Unsupported bitsPerDim: {} What it means
Thrown by AsymmetricHashingScorer.pack (or related packing logic) when bitsPerDim is not one of the supported values. The switch handles 1, 2, 4 (optimized), and 3, 8 (fallback), with a default that rejects everything else (e.g. 5, 6, 7, 9+). IllegalArgumentException — the caller passed a quantization bit-width this scorer cannot encode.
Source
Thrown at libs/simdvec/src/main/java/org/elasticsearch/simdvec/AsymmetricHashingScorer.java:85
byte[] packed = new byte[bitsPerDim * planeBytes];
switch (bitsPerDim) {
case 1 -> ESVectorUtil.pack1BitValues(rounded, packed);
case 2 -> ESVectorUtil.stride2BitValues(rounded, packed);
case 4 -> ESVectorUtil.stride4BitValues(rounded, packed);
case 3, 8 -> {
// TODO: optimized implementations
for (int j = 0; j < nDims; j++) {
int byteIdx = j >>> 3;
int bitIdx = 7 - (j & 7); // MSB-first
for (int p = 0; p < bitsPerDim; p++) {
if ((rounded[j] & (1 << p)) != 0) {
packed[p * planeBytes + byteIdx] |= (byte) (1 << bitIdx);
}
}
}
}
default -> throw new IllegalArgumentException("Unsupported bitsPerDim: " + bitsPerDim);
}
return packed;
}
/**
* Scores a single database vector from its packed bit-plane representation against a
* precomputed transformed query. This is the inner-loop method for posting list scoring.
* <p>
* The packed format is bitsPerDim bit-planes, each ceil(nDims/8) bytes, MSB-first.
* Codes represent centered levels. The unsigned code value is reconstructed from bit planes,
* then shifted back to centered by subtracting (numLevels-1)/2.
* dot = sum_j queryTransformed[j] * centeredCode[j]
* = sum over planes of (2^p * sum_of_qt_where_bit_p_set) - centerOffset * sumAll
*
* @param queryTransformed precomputed query @ W (raw projection, not centered)
* @param queryDotCentroid precomputed query . centroid for this cluster
* @param packedCodes bit-plane packed codesView on GitHub (pinned to db6a809a66)
Solutions
- Use one of the supported bitsPerDim values: 1, 2, 3, 4, or 8.
- Validate bitsPerDim at config/model-load time against the supported set and reject early with a clear error before reaching the scorer.
- If a new bit width is required, add an optimized (or fallback) case branch and a test before exposing it.
- Check the dense_vector / quantization config that produced the model for a typo or unsupported value.
Example fix
// before
int bitsPerDim = config.bitsPerDim(); // could be 6
scorer.pack(query, bitsPerDim);
// after
if (!Set.of(1,2,3,4,8).contains(config.bitsPerDim())) {
throw new IllegalArgumentException("bits_per_dim must be one of 1,2,3,4,8");
}
scorer.pack(query, config.bitsPerDim()); Defensive patterns
Strategy: validation
Validate before calling
private static final Set<Integer> SUPPORTED_BITS = Set.of(1, 2, 3, 4, 8);
if (!SUPPORTED_BITS.contains(bitsPerDim)) {
throw new IllegalArgumentException("bits_per_dim must be one of 1,2,3,4,8; got " + bitsPerDim);
} Prevention
- Restrict bitsPerDim to {1,2,3,4,8}.
- Validate at model/config load, not inside the scoring hot loop.
- Add an explicit case branch + test before exposing a new bit width.
When it happens
Trigger: Constructing/using an AsymmetricHashing model with bitsPerDim outside {1,2,3,4,8}; reading a quantization config whose bits_per_dim was set to an unsupported value; a model trained with a bit width the runtime scorer has not implemented.
Common situations: User-configured dense_vector quantization with an unusual bit width; model artifacts produced by a newer trainer exposing bit widths the runtime does not yet support; tests sweeping bit widths without gating on the supported set.
Related errors
- Unsupported query/index bits combination: {}/{}
- vector dimensions incompatible: {}!= {}
- attempt to retrieve score correction for different ord {} th
- bit must be between 1 and 8, but was: {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/2f0e25633aeeda2f.
Report an issue: GitHub.