influxdata/influxdb · error · Error

No row group found, cannot recover statistics

Error message

No row group found, cannot recover statistics

What it means

read_statistics returns a NoRowGroupSnafu error ("No row group found, cannot recover statistics") when the Parquet metadata contains zero row groups. Statistics are aggregated per row group, so an empty file cannot yield column summaries. Unlike the expect() panics, this is a proper Result error.

Solutions

  1. Check row count before writing: skip encoding empty RecordBatches
  2. Handle the Result from read_statistics and skip/reject empty files
  3. Re-flush from the source data rather than re-reading the empty file

Example fix

// caller-side guard
if batch.num_rows() == 0 {
    return Ok(None); // don't produce an empty parquet file
}
Defensive patterns

Strategy: validation

Validate before calling

if batch.num_rows() == 0 { return Ok(None); } // skip empty writes

Try / catch

match parquet_file.read_statistics(&schema) {
    Err(e) if matches!(e, ...NoRowGroup..) => return Ok(None),
    r => r?,
}

Prevention

When it happens

Trigger: Calling read_statistics (via assert_metadata or to_parquet_file) on a Parquet file whose footer reports no row groups — an empty or truncated file.

Common situations: Writing zero-row batches to Parquet, interrupted flushes leaving empty footers, files created by compaction over empty inputs.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

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

            file_metadata.key_value_metadata(),
        )
        .context(ArrowFromParquetFailureSnafu {})?;

        // The parquet reader will propagate any metadata keys present in the parquet
        // metadata onto the arrow schema. This will include the encoded IOxMetadata
        //
        // We strip this out to avoid false negatives when comparing schemas for equality,
        // as this metadata will vary from file to file
        let arrow_schema_ref = Arc::new(arrow_schema.with_metadata(Default::default()));

        arrow_schema_ref
            .try_into()
            .context(IoxFromArrowFailureSnafu {})
    }

    /// Read IOx statistics (including timestamp range) from parquet metadata.
    pub fn read_statistics(&self, schema: &Schema) -> Result<Vec<ColumnSummary>> {
        ensure!(!self.md.row_groups().is_empty(), NoRowGroupSnafu);

        let mut column_summaries = Vec::with_capacity(schema.len());

        for (row_group_idx, row_group) in self.md.row_groups().iter().enumerate() {
            let row_group_column_summaries =
                read_statistics_from_parquet_row_group(row_group, row_group_idx, schema)?;

            combine_column_summaries(&mut column_summaries, row_group_column_summaries);
        }

        Ok(column_summaries)
    }

    /// Estimate the memory consumption of this object and its contents
    pub fn size(&self) -> usize {
        // This is likely a wild under count as it doesn't include
        // memory pointed to in the `ParquetMetaData` structues.
        // Feature tracked in arrow-rs: https://github.com/apache/arrow-rs/issues/1729

View on GitHub (pinned to 06200ef96b)