quickwit-oss/tantivy · error
non-zero packed bits fit in u64
Error message
non-zero packed bits fit in u64
What it means
This is a Rust panic from an `expect` on `u64::checked_shl` inside `shift_packed_bits` in multi-terms aggregation. The function shifts a field's packed bits left by a computed shift amount, and the panic fires when `shift >= 64` (or bits would overflow), meaning the combined per-field bit offsets of the terms aggregation exceed the 64 bits available in a single packed key. The library assumes the sum of all field max_offsets stays within 64 bits; a mis-computed or corrupt pack layout violates that invariant.
Source
Thrown at src/aggregation/bucket/multi_terms/mod.rs:983
packs.push(FieldPack {
shift,
mask,
min_value,
max_offset,
});
shift += width;
}
packs.reverse();
Some(packs)
}
#[inline]
fn shift_packed_bits(bits: u64, shift: u32) -> u64 {
if bits == 0 {
0
} else {
bits.checked_shl(shift)
.expect("non-zero packed bits fit in u64")
}
}
fn compute_max_packed(packs: &[FieldPack]) -> u64 {
packs.iter().fold(0u64, |packed, field| {
packed | shift_packed_bits(field.max_offset, field.shift)
})
}
#[derive(Clone, Debug)]
struct PackedU64KeyPacking {
packs: Vec<FieldPack>,
}
/// Selects the key packing and bucket storage, then boxes the concrete collector.
fn build_multi_terms_collector<BucketSlot: BucketIdSlot>(
req: &mut AggregationsSegmentCtx,
node: &AggRefNode,View on GitHub (pinned to b5d8deb80c)
Solutions
- Reduce the number of fields in the multi_terms aggregation so the combined bit width fits in 64 bits.
- Check term/ordinal cardinality of the involved fields; split the aggregation or use a composite aggregation instead.
- If you maintain the code, return a Result from shift_packed_bits and surface a user-facing error instead of expecting.
- Reindex the field if a corrupt or oversized ordinal layout is suspected.
Example fix
// before
bits.checked_shl(shift).expect("non-zero packed bits fit in u64")
// after
bits.checked_shl(shift)
.ok_or_else(|| crate::AggregationError::Internal("packed bits overflow u64".to_string()))? Defensive patterns
Strategy: validation
Validate before calling
// Before issuing a multi_terms agg, bound the combined ordinal bit width of the fields.
fn packed_bits_fit_in_u64(field_max_offsets: &[u64]) -> bool {
field_max_offsets.iter().map(|o| 64 - o.leading_zeros()).sum::<u32>() <= 64
}
if !packed_bits_fit_in_u64(&offsets) {
// fall back to a composite aggregation instead of multi_terms
} Prevention
- Keep the number of multi_terms sub-fields small enough that their ordinal bit widths fit in 64 bits.
- Prefer composite aggregation for many-field grouping.
- Monitor term dictionary cardinality for fields used in multi_terms.
When it happens
Trigger: Calling a multi_terms aggregation whose per-field packed bit layout (`field.max_offset` + `field.shift`) exceeds 64 total bits, e.g. very high-cardinality or wide ordinal fields combined in one multi_terms agg, so `checked_shl(shift)` returns None and the expect panics.
Common situations: Multi-terms aggregation over many fields or fields with large term dictionaries where the sum of bit widths of all sub-fields overflows u64; index segments with unexpectedly large ordinals after mapping or index-version changes.
Related errors
- dictionary missing for str accessor
- could not convert to String
- Key length mismatch
- term dict returned non-UTF-8
- could not convert to String
AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05).
Data as JSON: /api/errors/c7e6307caff1ea84.
Report an issue: GitHub.