quickwit-oss/quickwit · error

input rg col ' ' has no max in stats — cannot determine…

Error message

input {input_idx} rg {rg_idx} col '{col_name}' has no max in stats — cannot determine prefix alignment

What it means

The max-side counterpart of require_eq: the row-group prefix column's statistics carry no max value, so the function cannot confirm that all rows in the row group share one constant prefix value and fails fast rather than producing a misaligned region key.

Solutions

  1. Rewrite input parquet files with complete min/max statistics enabled.
  2. Confirm the writer version and statistics settings used to produce the inputs.
  3. Check that encode_prefix_col_value matches the right Statistics variant for the column physical type so max is actually read.
Defensive patterns

Strategy: validation

Validate before calling

let stats = chunk.statistics().ok_or_else(|| anyhow!("no stats"))?;
if stats.max_bytes_opt().is_none() {
    return Err(anyhow!("chunk stats lack max"));
}

Try / catch

if e.to_string().contains("has no max in stats") {
    rewrite_with_full_stats(input)?;
    return retry_merge(input);
}

Prevention

When it happens

Trigger: encode_prefix_col_value → require_eq called on a chunk whose parquet Statistics has max = None, during extract_regions_from_metadata / streaming merge.

Common situations: Files written by writers that omit max stats; legacy or truncated statistics; corrupted metadata written by a mismatched parquet-rs version.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/bfb5d44d75d88515. Report an issue: GitHub.

Appendix: source

Thrown at quickwit/quickwit-parquet-engine/src/merge/streaming/region_grouping.rs:337

    key: &mut Vec<u8>,
) -> Result<()> {
    use parquet::file::statistics::Statistics;

    fn require_eq<T: PartialEq + std::fmt::Debug>(
        min: Option<T>,
        max: Option<T>,
        col_name: &str,
        rg_idx: usize,
        input_idx: usize,
    ) -> Result<T> {
        let min = min.ok_or_else(|| {
            anyhow!(
                "input {input_idx} rg {rg_idx} col '{col_name}' has no min in stats — cannot \
                 determine prefix alignment"
            )
        })?;
        let max = max.ok_or_else(|| {
            anyhow!(
                "input {input_idx} rg {rg_idx} col '{col_name}' has no max in stats — cannot \
                 determine prefix alignment"
            )
        })?;
        if min != max {
            bail!(
                "input {input_idx} rg {rg_idx} is NOT prefix-aligned on col '{col_name}': min \
                 ({:?}) != max ({:?}). Multi-RG inputs declaring `rg_partition_prefix_len >= 1` \
                 must carry one prefix-value per RG.",
                min,
                max,
            );
        }
        Ok(min)
    }

    fn encode_byte_array_value(
        min_bytes: Option<&[u8]>,

View on GitHub (pinned to a39730c5cd)