elastic/elasticsearch · error · IllegalArgumentException

[bitmap_terms] query expects a base64-encoded RoaringBitmap

Error message

[bitmap_terms] query expects a base64-encoded RoaringBitmap value

What it means

Thrown when the value string is not valid base64. The query first base64-decodes the value; if java.util.Base64.getDecoder().decode throws IllegalArgumentException (illegal character, wrong padding, etc.) it is wrapped in this IllegalArgumentException pointing at the encoding step.

Source

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

    @Override
    protected Query doToQuery(SearchExecutionContext context) throws IOException {
        MappedFieldType fieldType = context.getFieldType(fieldName);
        if (!(fieldType instanceof NumberFieldMapper.NumberFieldType numberFieldType)
            || (numberFieldType.numberType() != NumberFieldMapper.NumberType.INTEGER
                && numberFieldType.numberType() != NumberFieldMapper.NumberType.LONG)
            || (numberFieldType.isIndexedWithPoints() == false && numberFieldType.isIndexedWithTerms() == false)) {
            throw new IllegalArgumentException(
                "[bitmap_terms] query is not supported on field ["
                    + fieldName
                    + "]: only supported on [integer] and [long] fields indexed with points or terms"
            );
        }
        byte[] bitmapBytes;
        try {
            bitmapBytes = Base64.getDecoder().decode(value);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("[bitmap_terms] query expects a base64-encoded RoaringBitmap value", e);
        }
        BitmapValues values = switch (numberFieldType.numberType()) {
            case INTEGER -> integerValues(bitmapBytes);
            case LONG -> longValues(bitmapBytes);
            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);

View on GitHub (pinned to db6a809a66)

Solutions

  1. Encode the serialized bitmap bytes with standard base64 (java.util.Base64.getEncoder() or Python base64.standard_b64encode).
  2. Strip whitespace/newlines and any data-URL prefix before sending.
  3. If using base64url, translate -_ to +/ and trim padding as needed.

Example fix

// before (hex string)
{"bitmap_terms":{"field":"uid","value":"030100"}}
// after (base64 of the serialized bitmap)
{"bitmap_terms":{"field":"uid","value":"AwABAQ=="}}
Defensive patterns

Strategy: validation

Validate before calling

// Validate base64 (standard alphabet) before sending.
const RE = /^[A-Za-z0-9+/]*={0,2}$/;
function assertBase64(v) {
  if (!v || !RE.test(v) || v.length % 4 !== 0) {
    throw new Error("value is not valid standard base64");
  }
}

Prevention

When it happens

Trigger: Passing a hex-encoded bitmap instead of base64; passing a data-URL prefix like "data:...;base64,..."; base64 with URL-safe characters (-_) when standard decoder is used; corrupted/whitespace-padded string; empty string.

Common situations: Client library encodes with base64url without translating to standard base64; copy-paste truncation; reading the bitmap from a text channel that strips/replaces characters.

Related errors


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