influxdata/influxdb · warning · PersisterError

tried to serialize a parquet file with no rows

Error message

tried to serialize a parquet file with no rows

What it means

PersisterError::NoRows is returned when the Persister is asked to serialize a parquet file from a RecordBatch that contains zero rows. Parquet persistence is only meaningful for non-empty batches, so an empty batch is rejected explicitly rather than producing an empty file.

Solutions

  1. Skip persisting when `batch.num_rows() == 0` before calling the persister.
  2. Trace why an empty batch reached the persister (empty table vs over-aggressive filter).
  3. Guard snapshot/compaction tasks to no-op on empty tables.

Example fix

// before
persister.persist(batch).await?;
// after
if batch.num_rows() > 0 {
    persister.persist(batch).await?;
}
Defensive patterns

Strategy: validation

Validate before calling

if batch.num_rows() == 0 {
    return Ok(()); // nothing to persist
}

Prevention

When it happens

Trigger: Calling the persister's parquet-write path with an empty RecordBatch — e.g. persisting a table snapshot or query result that filtered everything out or a table with no data at flush time.

Common situations: Compaction/snapshot logic running on a table with no rows; a query predicate that matches nothing being fed to persist; a bug in upstream buffering yielding empty batches.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at influxdb3_write/src/persister.rs:62

use parquet::file::metadata::ParquetMetaData;
use parquet::file::properties::WriterProperties;
use tokio::sync::Semaphore;

#[derive(Debug, thiserror::Error)]
pub enum PersisterError {
    #[error("datafusion error: {0}")]
    DataFusion(#[from] DataFusionError),

    #[error("serde_json error: {0}")]
    SerdeJson(#[from] serde_json::Error),

    #[error("object_store error: {0}")]
    ObjectStore(#[from] object_store::Error),

    #[error("parquet error: {0}")]
    ParquetError(#[from] parquet::errors::ParquetError),

    #[error("tried to serialize a parquet file with no rows")]
    NoRows,

    #[error("parse int error: {0}")]
    ParseInt(#[from] std::num::ParseIntError),

    #[error("unexpected persister error: {0:?}")]
    Unexpected(#[from] anyhow::Error),

    #[error("table snapshot persistence task panicked: {0}")]
    TableSnapshotPersistenceTaskFailed(#[source] tokio::task::JoinError),

    #[error("snapshot manifest parse task panicked: {0}")]
    SnapshotParseTaskFailed(#[source] tokio::task::JoinError),

    #[error("table index error: {0}")]
    TableIndexPathError(#[source] crate::paths::PathError),

    #[error("object meta is missing filename")]

View on GitHub (pinned to 06200ef96b)