influxdata/influxdb · error · TimestampMinMaxError

Could not find a time column

Error message

Could not find a time column

What it means

TimestampMinMaxError::NoTimeColumnFound — the Arrow schema derived from the Parquet file contains no 'time' column, so no timestamp range can be computed. The helper is IOx-specific and requires the standard time column.

Solutions

  1. Verify the file's schema includes the 'time' column before extraction
  2. Handle the NoTimeColumnFound variant and skip files that are not IOx-shaped
  3. Ensure all write paths create the time column with TIME_COLUMN_NAME

Example fix

// caller-side guard
let fields: Vec<_> = schema.fields().iter().map(|f| f.name().as_str()).collect();
if !fields.contains(&"time") { return Err("not an IOx file"); }
Defensive patterns

Strategy: validation

Validate before calling

let names: Vec<&str> = arrow_schema.fields().iter().map(|f| f.name().as_str()).collect();
if !names.contains(&"time") { return Err(anyhow!("missing time column")); }

Type guard

fn has_time(schema: &Schema) -> bool { schema.column_with_name("time").is_some() }

Try / catch

match ts_min_max {
    Err(TimestampMinMaxError::NoTimeColumnFound) => return Ok(TimestampRange::default()),
    other => other?,
}

Prevention

When it happens

Trigger: Calling the timestamp min/max extraction on a Parquet file whose schema lacks a column named 'time' (foreign files, renamed columns).

Common situations: Processing non-IOx Parquet files, schema migrations that renamed the time field, compaction outputs missing the time column.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/ad6961dd3197c8af. Report an issue: GitHub.

Appendix: source

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

        .row_groups()
        .iter()
        .map(timestamp_min_max)
        .collect::<Result<Vec<_>, _>>()?;
    let file_timestamp_min_max = timestamp_min_maxes
        .into_iter()
        .reduce(|acc, i| acc.union(&i));

    Ok(file_timestamp_min_max)
}

/// Errors that may happen while collecting the min and max timestamps
#[expect(missing_docs)]
#[derive(Debug, Error)]
pub enum TimestampMinMaxError {
    #[error("Could not convert Parquet schema to Arrow schema: {0}")]
    SchemaConversion(#[from] parquet::errors::ParquetError),

    #[error("Could not find a time column")]
    NoTimeColumnFound,

    #[error("Could not find time column statistics")]
    NoColumnStatisticsFound,

    #[error("Expected time column to have type Int64; instead found {actual:?}")]
    IncorrectTimeColumnType { actual: parquet::basic::Type },
}

fn timestamp_min_max(
    row_group: &ParquetRowGroupMetaData,
) -> Result<TimestampMinMax, TimestampMinMaxError> {
    let statistics = row_group
        .columns()
        .iter()
        .find(|c| c.column_descr().name() == schema::TIME_COLUMN_NAME)
        .ok_or(TimestampMinMaxError::NoTimeColumnFound)?
        .statistics()

View on GitHub (pinned to 06200ef96b)