{"record":{"id":"4c29c33f28d31fe6","repo":"elastic/elasticsearch","slug":"bitmap-terms-query-expects-a-base64-encoded-roar","errorCode":null,"errorMessage":"[bitmap_terms] query expects a base64-encoded RoaringBitmap value","messagePattern":"\\[bitmap_terms\\] query expects a base64-encoded RoaringBitmap value","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/bitmap/src/main/java/org/elasticsearch/index/query/bitmapterms/BitmapTermsQueryBuilder.java","lineNumber":166,"sourceCode":"\n    @Override\n    protected Query doToQuery(SearchExecutionContext context) throws IOException {\n        MappedFieldType fieldType = context.getFieldType(fieldName);\n        if (!(fieldType instanceof NumberFieldMapper.NumberFieldType numberFieldType)\n            || (numberFieldType.numberType() != NumberFieldMapper.NumberType.INTEGER\n                && numberFieldType.numberType() != NumberFieldMapper.NumberType.LONG)\n            || (numberFieldType.isIndexedWithPoints() == false && numberFieldType.isIndexedWithTerms() == false)) {\n            throw new IllegalArgumentException(\n                \"[bitmap_terms] query is not supported on field [\"\n                    + fieldName\n                    + \"]: only supported on [integer] and [long] fields indexed with points or terms\"\n            );\n        }\n        byte[] bitmapBytes;\n        try {\n            bitmapBytes = Base64.getDecoder().decode(value);\n        } catch (IllegalArgumentException e) {\n            throw new IllegalArgumentException(\"[bitmap_terms] query expects a base64-encoded RoaringBitmap value\", e);\n        }\n        BitmapValues values = switch (numberFieldType.numberType()) {\n            case INTEGER -> integerValues(bitmapBytes);\n            case LONG -> longValues(bitmapBytes);\n            default -> throw new AssertionError(\"unexpected number type [\" + numberFieldType.numberType() + \"]\");\n        };\n        // The two queries differ only in which index structure they merge against; the field's width\n        // is carried by the BitmapValues.\n        if (numberFieldType.isIndexedWithTerms()) {\n            return new BitmapTermsQuery(fieldName, values);\n        }\n        return new BitmapBKDQuery(fieldName, values);\n    }\n\n    private static IntBitmap integerValues(byte[] bitmapBytes) {\n        IntBitmap bitmap;\n        try {\n            bitmap = IntBitmap.deserialize(bitmapBytes);","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/bitmap/src/main/java/org/elasticsearch/index/query/bitmapterms/BitmapTermsQueryBuilder.java#L148-L184","documentation":"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.","triggerScenarios":"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.","commonSituations":"Client library encodes with base64url without translating to standard base64; copy-paste truncation; reading the bitmap from a text channel that strips/replaces characters.","solutions":["Encode the serialized bitmap bytes with standard base64 (java.util.Base64.getEncoder() or Python base64.standard_b64encode).","Strip whitespace/newlines and any data-URL prefix before sending.","If using base64url, translate -_ to +/ and trim padding as needed."],"exampleFix":"// before (hex string)\n{\"bitmap_terms\":{\"field\":\"uid\",\"value\":\"030100\"}}\n// after (base64 of the serialized bitmap)\n{\"bitmap_terms\":{\"field\":\"uid\",\"value\":\"AwABAQ==\"}}","handlingStrategy":"validation","validationCode":"// Validate base64 (standard alphabet) before sending.\nconst RE = /^[A-Za-z0-9+/]*={0,2}$/;\nfunction assertBase64(v) {\n  if (!v || !RE.test(v) || v.length % 4 !== 0) {\n    throw new Error(\"value is not valid standard base64\");\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always encode with java.util.Base64.getEncoder() or Python base64.standard_b64encode.","Avoid base64url; strip whitespace and data-URL prefixes."],"tags":["bitmap-terms","base64","encoding","elasticsearch"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}