elastic/elasticsearch · error · IllegalArgumentException

[bitmap_terms] query on [integer] field only supports non-ne

Error message

[bitmap_terms] query on [integer] field only supports non-negative values (0 to 2147483647)

What it means

Thrown by integerValues after a successful 32-bit RoaringBitmap deserialize when the bitmap contains any value in the negative int range. integer fields in Elasticsearch are signed 32-bit, but bitmap_terms restricts to the non-negative range [0, 2147483647] because that is the meaningful domain for matching indexed integer point values.

Source

Thrown at modules/bitmap/src/main/java/org/elasticsearch/index/query/bitmapterms/BitmapTermsQueryBuilder.java:189

            default -> throw new AssertionError("unexpected number type [" + numberFieldType.numberType() + "]");
        };
        // The two queries differ only in which index structure they merge against; the field's width
        // is carried by the BitmapValues.
        if (numberFieldType.isIndexedWithTerms()) {
            return new BitmapTermsQuery(fieldName, values);
        }
        return new BitmapBKDQuery(fieldName, values);
    }

    private static IntBitmap integerValues(byte[] bitmapBytes) {
        IntBitmap bitmap;
        try {
            bitmap = IntBitmap.deserialize(bitmapBytes);
        } catch (Exception e) {
            throw new IllegalArgumentException("[bitmap_terms] query value is not a valid serialized RoaringBitmap", e);
        }
        if (bitmap.hasNegativeValues()) {
            throw new IllegalArgumentException(
                "[bitmap_terms] query on [integer] field only supports non-negative values (0 to 2147483647)"
            );
        }
        return bitmap;
    }

    private static LongBitmap longValues(byte[] bitmapBytes) {
        LongBitmap bitmap;
        try {
            bitmap = LongBitmap.deserializePortable(bitmapBytes);
        } catch (Exception e) {
            throw new IllegalArgumentException(
                "[bitmap_terms] query value is not a valid serialized 64-bit RoaringBitmap in the portable format",
                e
            );
        }
        if (bitmap.hasNegativeValues()) {
            throw new IllegalArgumentException(

View on GitHub (pinned to db6a809a66)

Solutions

  1. Ensure all values in the 32-bit bitmap are in [0, 2147483647].
  2. If you need values above 2^31-1, switch the field to long and supply a 64-bit portable bitmap.
  3. Filter or reject high-bit values on the producer side before serializing.

Example fix

// before
bitmap.add(3000000000L) // > Integer.MAX_VALUE
// after
longField mapping + 64-bit portable bitmap containing 3000000000L
Defensive patterns

Strategy: validation

Validate before calling

// Reject any value above Integer.MAX_VALUE before serializing for an integer field.
for (long v : values) {
  if (v < 0 || v > Integer.MAX_VALUE) {
    throw new IllegalArgumentException("integer bitmap value out of range: " + v);
  }
}

Prevention

When it happens

Trigger: A 32-bit RoaringBitmap that has any of bits in the range interpreted as >= 2^31 set (i.e. values that would be negative java ints), or a bitmap built from unsigned values that overflow into the sign bit.

Common situations: Client treats the bitmap as unsigned 32-bit while the field is signed; bit-flip from a hashing step that produces high-bit values.

Related errors


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