risingwavelabs/risingwave · error · SinkError::Config
`compaction.write_parquet_max_row_group_bytes` must be…
Error message
`compaction.write_parquet_max_row_group_bytes` must be greater than 0
What it means
Iceberg sink configuration validation in `from_btreemap` rejects `compaction.write_parquet_max_row_group_bytes` set to 0, because a Parquet row group must hold at least some bytes for the writer to function. The value is optional (`Option<u64>`), so only an explicit `Some(0)` is rejected; unset uses the default.
Solutions
- Set `compaction.write_parquet_max_row_group_bytes` to a positive byte value (e.g. 134217728 for 128MB).
- Remove the property entirely to use the library default.
- Check the SQL WITH clause or properties btreemap for a 0 value coming from an env variable or template.
- If the intent is to disable compaction tuning, use the dedicated toggle instead of a 0 byte limit.
Example fix
// before
let mut props = BTreeMap::new();
props.insert("compaction.write_parquet_max_row_group_bytes".to_string(), "0".to_string());
// after
props.insert("compaction.write_parquet_max_row_group_bytes".to_string(), "134217728".to_string()); Defensive patterns
Strategy: validation
Validate before calling
if let Some(bytes) = props.get("compaction.write_parquet_max_row_group_bytes") {
if bytes.parse::<u64>().map_err(|_| "invalid int")? == 0 {
return Err("write_parquet_max_row_group_bytes must be > 0");
}
} Type guard
fn valid_row_group_bytes(v: Option<u64>) -> bool { v.map_or(true, |b| b > 0) } Prevention
- Never set compaction sizes to 0 to disable features; unset them instead
- Lint sink WITH options before submitting CREATE SINK
- Guard templated values with max(1, computed)
When it happens
Trigger: Creating an Iceberg sink (CREATE SINK ... WITH options) or programmatically building sink config via `IcebergConfig::from_btreemap` with property `compaction.write_parquet_max_row_group_bytes` equal to `0`.
Common situations: Developers experimenting with row-group tuning set the value to 0 to 'disable' the limit, or templating scripts interpolate a computed value that evaluates to 0.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- `compaction-interval-sec` must be greater than 0 when…
- `compaction.max_snapshots_num` must be greater than 0, got
- `compaction.target_file_size_mb` must be greater than 0
- `compaction.type` must not be set when `write_mode` is…
- `compaction.write_parquet_compression` must be one of
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/df9ec48a40ce3b00.
Report an issue: GitHub.
Appendix: source
Thrown at src/connector/src/sink/iceberg/config.rs:673
return Err(SinkError::Config(anyhow!(
"`compaction.delete_files_count_threshold` must be greater than 0"
)));
}
if config.target_file_size_mb == Some(0) {
return Err(SinkError::Config(anyhow!(
"`compaction.target_file_size_mb` must be greater than 0"
)));
}
if config.write_parquet_max_row_group_rows == Some(0) {
return Err(SinkError::Config(anyhow!(
"`compaction.write_parquet_max_row_group_rows` must be greater than 0"
)));
}
if config.write_parquet_max_row_group_bytes == Some(0) {
return Err(SinkError::Config(anyhow!(
"`compaction.write_parquet_max_row_group_bytes` must be greater than 0"
)));
}
if config.manifest_rewrite_target_size_bytes == Some(0) {
return Err(SinkError::Config(anyhow!(
"`manifest_rewrite_target_size_bytes` must be greater than 0"
)));
}
if config.manifest_rewrite_min_count_to_merge == Some(0) {
return Err(SinkError::Config(anyhow!(
"`manifest_rewrite_min_count_to_merge` must be greater than 0"
)));
}
// Validate table identifier (e.g., database.name should not contain dots)
configView on GitHub (pinned to 6469eb736d)