influxdata/influxdb · error
num_row_groups_in_parallel should be above zero
Error message
num_row_groups_in_parallel should be above zero
What it means
ParquetStorage::with_parallel_write_settings wraps its two usize arguments into NonZeroUsize via NonZeroUsize::new(..).expect("num_row_groups_in_parallel should be above zero") (and a sibling expect for num_columns_in_parallel). Passing 0 for either argument makes NonZeroUsize::new return None and panics immediately; the # Panics doc section states this contract. It is a fail-fast config-validation panic at builder time, before any IO happens.
Source
Thrown at core/parquet_file/src/storage.rs:247
parquet_write_parallelization_settings: Default::default(),
}
}
/// Provide settings for parallelized writes. Settings determine the
/// amount of parallelization per row group and per column.
///
/// # Panics
///
/// This will panic if an invalid usize (not > 0) is used.
pub fn with_parallel_write_settings(
self,
num_row_group_writers: usize,
num_column_writers_across_row_groups: usize,
) -> Self {
Self {
parquet_write_parallelization_settings: ParallelParquetWriterOptions::new(
NonZeroUsize::new(num_row_group_writers)
.expect("num_row_groups_in_parallel should be above zero"),
NonZeroUsize::new(num_column_writers_across_row_groups)
.expect("num_columns_in_parallel should be above zero"),
),
..self
}
}
/// Get underlying object store.
pub fn object_store(&self) -> &Arc<DynObjectStore> {
&self.object_store
}
/// Get ID.
pub fn id(&self) -> StorageId {
self.id
}
/// Fake DataFusion context for testing that contains this storeView on GitHub (pinned to d28e26e048)
Solutions
- Pass a value >= 1 for both arguments; if deriving from a formula, clamp with .max(1).
- Parse config as NonZeroUsize (or validate > 0 and reject the config at load time) so 0 never reaches the builder.
- Round instead of truncate when converting fractional parallelism to usize.
- Document/enforce a minimum in your settings layer (e.g. num_row_groups: NonZeroUsize in the config struct).
Example fix
// before let storage = storage.with_parallel_write_settings(0, num_columns); // panics // after let storage = storage.with_parallel_write_settings(num_row_groups.max(1), num_columns.max(1));
Defensive patterns
Strategy: validation
Validate before calling
// validate config before building the storage
let num_row_groups = config.num_row_group_writers; // from CLI/env/file
if num_row_groups == 0 || config.num_column_writers_across_row_groups == 0 {
return Err("parallel write settings must be >= 1".into());
}
let storage = storage.with_parallel_write_settings(num_row_groups, config.num_column_writers_across_row_groups); Type guard
// carry NonZeroUsize through your config so 0 is unrepresentable
fn parse_parallelism(raw: &str) -> Result<NonZeroUsize, String> {
raw.parse::<usize>()
.ok()
.and_then(NonZeroUsize::new)
.ok_or_else(|| format!("'{raw}' must be a positive integer"))
} Prevention
- Model counts as NonZeroUsize in config schemas (serde supports it directly).
- Clamp computed parallelism with .max(1) instead of truncating fractional formulas to usize.
- Fail config load with a clear message on zero parallelism instead of panicking inside the builder.
- Read the builder's # Panics doc section before wiring raw config values into with_parallel_write_settings.
When it happens
Trigger: Calling with_parallel_write_settings(0, n) or (n, 0); typical sources are CLI/env config parsed straight into usize where unset maps to 0, or computed parallelism like f64 rounding/truncation yielding 0 (e.g. cores*0.25 with 0-1 cores).
Common situations: Config plumbing that defaults parallelism to 0 when a knob is missing; formulas deriving row-group writer counts from table width (n_columns * factor) that floor to 0 for narrow tables; deployments on tiny containers reporting 1 CPU with a fractional multiplier.
Related errors
- ghost queue is NOT empty
- invalid IOx metadata
- failed to read encoded schema
- invalid statistics
- no time column in metadata statistics
AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16).
Data as JSON: /api/errors/696a9cd5329237b1.
Report an issue: GitHub.