apache/druid · error · IllegalStateException
bitmapEncoding[ ] does not match indexSpec.bitmap[ ]
Error message
bitmapEncoding[%s] does not match indexSpec.bitmap[%s]
What it means
NestedCommonFormatColumnFormatSpec.getEffectiveFormatSpec() builds the effective column format by combining the persisted columnFormatSpec with the segment indexSpec. If the builder's bitmapEncoding (which only the internal builder may set, never the JSON spec) disagrees with indexSpec.getBitmapSerdeFactory(), an internal invariant is violated and it throws an ISE.
Solutions
- Regenerate the segment: remove the offending column's formatSpec JSON so bitmapEncoding is derived solely from indexSpec.
- Set indexSpec.bitmap in the ingestion spec to the same bitmap serde as any explicitly constructed builder.
- Re-ingest the data to produce fresh, consistent segment metadata.
- Check for external tooling writing segment descriptors directly and stop it from setting bitmapEncoding.
Example fix
// before: conflicting config in ingestion spec
// "indexSpec": {"bitmap": {"type": "roaring"}}, column format built with CONCISE bitmapEncoding
// after: let indexSpec drive it
// NestedCommonFormatColumnFormatSpec.builder() // do NOT call setBitmapEncoding
// .setBitmapEncoding(indexSpec.getBitmapSerdeFactory()).build() Defensive patterns
Strategy: validation
Validate before calling
// ensure any explicitly constructed format spec matches indexSpec before use
if (formatSpec != null && formatSpec.getBitmapEncoding() != null &&
!formatSpec.getBitmapEncoding().equals(indexSpec.getBitmapSerdeFactory())) {
throw new IllegalArgumentException("bitmapEncoding must match indexSpec.bitmap");
} Try / catch
try {
spec = NestedCommonFormatColumnFormatSpec.getEffectiveFormatSpec(indexSpec, columnFormatSpec, ...);
} catch (IllegalStateException e) {
if (e.getMessage().contains("bitmapEncoding")) {
log.error(e, "Column format bitmapEncoding conflicts with indexSpec");
} else throw e;
} Prevention
- Never set bitmapEncoding in column format JSON; let indexSpec drive it
- Keep indexSpec.bitmap consistent across ingestion and compaction specs
- Avoid hand-editing segment metadata
When it happens
Trigger: Deserializing a nested column format spec whose JSON contains a bitmapEncoding that conflicts with the segment metadata's indexSpec bitmap serde factory; corrupted or hand-edited segment metadata.
Common situations: Hand-modified or programmatically written segment metadata where bitmapEncoding was set via JSON against the documented restriction; mismatch between writer's indexSpec and column metadata after tampering or partial writes.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- At most one of 'druid.broker.segment.watchedTiers' and…
- Cannot copy [%,d] bytes, only have [%,d] buffered
- Cannot delete [%,d] bytes, only have [%,d] buffered
- Cannot merge columns of type
- Cannot mix sortable and unsortable key columns
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/af5aae5345b7cc70.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/nested/NestedCommonFormatColumnFormatSpec.java:78
/**
* Create a {@link NestedCommonFormatColumnFormatSpec} with all fields fully populated. Values are populated in the following order:
* <ul>
* <li> value in the given column format spec, if non-null </li>
* <li> value in {@link IndexSpec#getAutoColumnFormatSpec()}, if non-null </li>
* <li> fall back to equivalent fields on {@link IndexSpec} itself if applicable </li>
* <li> hard coded defaults in {@link #DEFAULT}</li>
* </ul>
*/
public static NestedCommonFormatColumnFormatSpec getEffectiveFormatSpec(
@Nullable NestedCommonFormatColumnFormatSpec columnFormatSpec,
IndexSpec indexSpec
)
{
final Builder builder = columnFormatSpec == null ? builder() : builder(columnFormatSpec);
// this is a defensive check, the json spec of the column can't set this, only the builder can
if (builder.bitmapEncoding != null && !builder.bitmapEncoding.equals(indexSpec.getBitmapSerdeFactory())) {
throw new ISE(
"bitmapEncoding[%s] does not match indexSpec.bitmap[%s]",
builder.bitmapEncoding,
indexSpec.getBitmapSerdeFactory()
);
}
builder.setBitmapEncoding(indexSpec.getBitmapSerdeFactory());
final NestedCommonFormatColumnFormatSpec defaultSpec;
if (indexSpec.getAutoColumnFormatSpec() != null) {
defaultSpec = indexSpec.getAutoColumnFormatSpec();
} else {
defaultSpec = DEFAULT;
}
if (builder.longFieldBitmapIndexType == null) {
if (defaultSpec.getLongFieldBitmapIndexType() != null) {
builder.setLongFieldBitmapIndexType(defaultSpec.getLongFieldBitmapIndexType());
} else {View on GitHub (pinned to 9b90983fd2)