influxdata/influxdb · error

no min time statistic

Error message

no min time statistic

What it means

After finding the time column, derive_min_max_time matches Statistics::I64(stats) and unwraps stats.min.expect("no min time statistic") (and max on the next line). Parquet column statistics are optional: writers can disable them, and an all-null column has no min/max. When the time column exists but its statistics carry no min, this expect panics.

Source

Thrown at core/parquet_file/src/metadata.rs:577

/// A [`RecordBatch`] serialized without the embedded metadata found in the
/// IOx [`Schema`] type will cause a statistic resolution failure due to
/// lack of the IOx field type metadata for the time column. Batches
/// produced from the through the IOx write path always include this
/// metadata.
///
/// [`RecordBatch`]: arrow::record_batch::RecordBatch
pub fn derive_min_max_time(stats: Vec<ColumnSummary>) -> TimestampRange {
    let time_summary = stats
        .into_iter()
        .find(|v| v.name == TIME_COLUMN_NAME)
        .expect("no time column in metadata statistics");

    assert_eq!(time_summary.influxdb_type, InfluxDbType::Timestamp);

    // Extract the min/max timestamps.
    match time_summary.stats {
        Statistics::I64(stats) => {
            let min = Timestamp::new(stats.min.expect("no min time statistic"));
            let max = Timestamp::new(stats.max.expect("no max time statistic"));
            TimestampRange { min, max }
        }
        _ => panic!("unexpected physical type for timestamp column"),
    }
}
/// Parquet metadata with IOx-specific wrapper.
#[derive(Clone, PartialEq, Eq)]
pub struct IoxParquetMetaData {
    /// [Apache Parquet] metadata as freestanding [Apache Thrift]-encoded, and [Zstandard]-compressed bytes.
    ///
    /// This can be used to store metadata separate from the related payload data. The usage of [Apache Thrift] allows the
    /// same stability guarantees as the usage of an ordinary [Apache Parquet] file. To encode a thrift message into bytes
    /// the [Thrift Compact Protocol] is used.
    ///
    /// [Apache Parquet]: https://parquet.apache.org/
    /// [Apache Thrift]: https://thrift.apache.org/
    /// [Thrift Compact Protocol]: https://github.com/apache/thrift/blob/master/doc/specs/thrift-compact-protocol.md

View on GitHub (pinned to d28e26e048)

Solutions

  1. Re-write the file with column statistics enabled (arrow-rs/parquet writer default enables them).
  2. If calling derive_min_max_time directly, pre-check the time summary's stats have min/max Some before calling, and skip or compute from data otherwise.
  3. Validate files coming from external sources with a parquet-inspection step (footer statistics present for the time column) before cataloging.
  4. For genuinely empty time columns, write at least one row or handle the empty-range case in your tooling before IOx paths see the file.

Example fix

// before
let range = derive_min_max_time(stats);

// after
let time = stats.iter().find(|v| v.name == TIME_COLUMN_NAME);
match time.map(|t| &t.stats) {
    Some(Statistics::I64(s)) if s.min.is_some() && s.max.is_some() => {
        let range = derive_min_max_time(stats);
        // ...
    }
    _ => return Err("time column lacks min/max statistics".into()),
}
Defensive patterns

Strategy: validation

Validate before calling

// verify min/max statistics exist for the time column before deriving the range
fn time_stats_complete(stats: &[ColumnSummary]) -> bool {
    stats.iter().any(|v| {
        v.name == TIME_COLUMN_NAME
            && matches!(&v.stats, Statistics::I64(s) if s.min.is_some() && s.max.is_some())
    })
}

if !time_stats_complete(&stats) {
    return Err("time column lacks min/max statistics (writer omitted them?)".into());
}

Try / catch

let range = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
    derive_min_max_time(stats.clone())
}));
if let Err(_) = range {
    return Err(CatalogError::IncompleteTimeStatistics.into());
}

Prevention

When it happens

Trigger: to_parquet_file / derive_min_max_time on a file whose time-column chunk statistics were not written — writer configured with statistics disabled, a null-only time column, or a writer version that omits min/max for some encodings.

Common situations: Externally generated parquet written with parquet.statistics_enabled=false; empty or all-null test batches; files written by old/limited parquet writers that skip min/max for int64 columns.

Related errors


AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16). Data as JSON: /api/errors/3e8b788e6a9a0af1. Report an issue: GitHub.