elastic/elasticsearch · error · IllegalArgumentException

[bitmap_terms] query value is not a valid serialized 64-bit

Error message

[bitmap_terms] query value is not a valid serialized 64-bit RoaringBitmap in the portable format

What it means

Thrown by longValues when LongBitmap.deserializePortable fails on the decoded bytes. The bytes were valid base64 but do not form a valid 64-bit RoaringBitmap in the portable format (the format produced by Roaring64NavigableMap.serializePortable). A common cause is supplying bytes from the non-portable serialize() method, which uses a different layout.

Source

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

        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(
                "[bitmap_terms] query on [long] field only supports non-negative values (0 to 9223372036854775807)"
            );
        }
        return bitmap;
    }

    @Override
    protected int doHashCode() {
        return Objects.hash(fieldName, value);
    }

    @Override

View on GitHub (pinned to db6a809a66)

Solutions

  1. For long fields, call Roaring64NavigableMap.serializePortable (java) or pyroaring BitMap64.serialize, then base64-encode.
  2. Do not reuse a 32-bit bitmap payload on a long field; regenerate in 64-bit portable format.
  3. Confirm the client Roaring library version produces the portable layout the server expects.

Example fix

// before: non-portable serialize
bytes = bitmap.serialize()
// after: portable format for long field
bytes = bitmap.serializePortable()
Defensive patterns

Strategy: validation

Validate before calling

// Round-trip the 64-bit bitmap via deserializePortable on the client.
import org.roaringbitmap.longlong.Roaring64NavigableMap;
byte[] bytes = bitmap.serializePortable();
Roaring64NavigableMap probe = new Roaring64NavigableMap();
probe.deserializePortable(DataInput.wrap(bytes));
String value = Base64.getEncoder().encodeToString(bytes);

Prevention

When it happens

Trigger: Calling Roaring64NavigableMap.serialize (default/non-portable) instead of serializePortable on the client; supplying a 32-bit bitmap payload to a long field; truncated or version-mismatched bytes.

Common situations: Java client forgets to call serializePortable specifically; pyroaring version mismatch; copy between integer/long fields without re-serializing.

Related errors


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