influxdata/influxdb · error · CodecError
no rows to serialise
Error message
no rows to serialise
What it means
CodecError::NoRows, raised when the result stream produced at least one RecordBatch but every batch contained zero rows. Writing this would upload an empty Parquet file to object storage, so the library rejects it. Distinguishes 'no batches' (152) from 'batches exist but all empty'.
Solutions
- Count total rows across batches before serialising and skip the write/upload when the count is zero
- Investigate why the query returns zero rows (predicate bounds, partition pruning)
- Compact or drop empty data upstream so empty batches never reach the serialiser
- If empty files are valid for your workflow, handle this variant explicitly and bypass the upload
Example fix
// before
let rows: usize = batches.iter().map(|b| b.num_rows()).sum();
write_parquet(batches.into_iter())?; // fails with NoRows when rows == 0
// after
let rows: usize = batches.iter().map(|b| b.num_rows()).sum();
if rows == 0 { return Ok(None); }
write_parquet(batches.into_iter())?; Defensive patterns
Strategy: validation
Validate before calling
let rows: usize = batches.iter().map(|b| b.num_rows()).sum();
if rows == 0 {
return Ok(None); // all batches were empty
} Try / catch
match res {
Err(CodecError::NoRows) => info!("query produced 0 rows; skipping empty file upload"),
other => other?,
} Prevention
- Sum num_rows across batches before writing, not just batch count
- Filter out zero-row batches early in the pipeline
- Alert on persist paths that receive all-empty streams — often a predicate bug
When it happens
Trigger: A DataFusion plan yields batches with schema but 0 rows (common with projection/limit/filter nodes) and the stream is handed to the Parquet codec.
Common situations: Queries matching no rows where the executor still emits empty batches (e.g. after a filter on an empty partition), time-range predicates covering no data, or dedup/limit logic draining all rows.
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
- no record batches to convert
- failed to write parquet file
- parquet error
- tried to serialize a parquet file with no rows
- arrow error
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/f43e5b233510f8d7.
Report an issue: GitHub.
Appendix: source
Thrown at core/parquet_file/src/serialize.rs:65
/// ensure read and write work well together
const _: () = assert!(ROW_GROUP_WRITE_SIZE.is_multiple_of(BATCH_SIZE));
/// [`RecordBatch`] to Parquet serialisation errors.
///
/// [`RecordBatch`]: arrow::record_batch::RecordBatch
#[derive(Debug, Error)]
pub enum CodecError {
/// The result stream contained no batches.
#[error("no record batches to convert")]
NoRecordBatches,
/// The result stream contained at least one [`RecordBatch`] and all
/// instances yielded by the stream contained 0 rows.
///
/// This would result in an empty file being uploaded to object store.
///
/// [`RecordBatch`]: arrow::record_batch::RecordBatch
#[error("no rows to serialise")]
NoRows,
/// A DataFusion error during the plan execution.
///
/// Of note: a ResourcesExhaused error likely means the buffer
/// used for parquet data became too large.
#[error(transparent)]
DataFusion(Box<DataFusionError>),
/// Serialising the [`IoxMetadata`] to protobuf-encoded bytes failed.
#[error("failed to serialize iox metadata: {0}")]
MetadataSerialisation(#[from] prost::EncodeError),
/// Writing the parquet file failed with the specified error.
#[error("failed to build parquet file: {0}")]
Writer(#[from] ParquetError),
/// Attempting to clone a handle to the provided write sink failed.View on GitHub (pinned to 06200ef96b)