risingwavelabs/risingwave · error · HummockError
COW compaction must produce at most one table-scoped plan, g
Error message
COW compaction must produce at most one table-scoped plan, got {} What it means
Each copy-on-write compaction plan publishes a complete table state to the main branch, so multiple independent COW plans would overwrite one another instead of composing their rewrites. After planning, create_task_execution asserts that a COW kind yields at most one plan; if the planner produced more than one, the task fails with this error before execution.
Source
Thrown at src/storage/src/hummock/compactor/iceberg_compaction/iceberg_compactor_runner.rs:1013
table
.metadata()
.snapshot_for_ref(&branch)
.map(|snapshot| {
vec![CompactionPlan::new(
FileGroup::empty(),
branch.clone(),
snapshot.snapshot_id(),
)]
})
.unwrap_or_default()
} else {
compaction_plans
};
// Each COW plan publishes a complete table state to `main`, so independent plans could
// overwrite one another instead of composing their rewrites.
if compaction_kind.is_copy_on_write() && compaction_plans.len() > 1 {
return Err(HummockError::compaction_executor(anyhow::anyhow!(
"COW compaction must produce at most one table-scoped plan, got {}",
compaction_plans.len()
)));
}
if compaction_plans.is_empty() {
tracing::info!(
iceberg_component = "compaction_worker",
iceberg_operation = "plan_task",
task_id = %task_id,
sink_id = sink_id,
task_type = ?compaction_kind,
table = %table_ident,
branch = %branch,
"iceberg_compaction_task_skipped_no_files",
);
return Ok(IcebergTaskExecution {
sink_id,View on GitHub (pinned to 6469eb736d)
Solutions
- Retry the compaction — if the planner intermittently split the plan, a fresh planning round may yield a single plan.
- Reduce compaction scope (e.g. run Full COW compaction on smaller tables/partitions) so a single table-scoped plan suffices.
- Verify the planner configuration (target_file_size_mb, group sizing options like target_binpack_group_size_mb) isn't forcing plan fragmentation; tune them to consolidate.
- If reproducible, this indicates a planner/COW invariant bug — report with the plan contents from the logs.
Defensive patterns
Strategy: try-catch
Try / catch
let plans = plan_compaction(&table, kind).await?;
if kind.is_copy_on_write() && plans.len() > 1 {
tracing::error!(count = plans.len(), "COW planner produced multiple plans; re-planning");
return retry_with_single_plan().await;
} Prevention
- Keep COW compaction scope small enough for a single table-scoped plan (partition-level Full compaction).
- Tune group sizing configs (target_binpack_group_size_mb, min_group_*) to avoid plan fragmentation.
- Treat repeated occurrences as a planner bug and report with plan logs.
When it happens
Trigger: IcebergCompactionKind::is_copy_on_write() is true and compaction_plans.len() > 1 after planning in create_task_execution — the planner generated multiple table-scoped plans for a COW task.
Common situations: Internal planner bug or a table state (very large table partitioned into many groups) that causes the planner to split a COW compaction into several plans; a config combination (COW write mode + multi-plan-producing strategy) that the planner doesn't guard upstream.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- compact_with_plan returned no result for a non-empty iceberg
- No snapshot found with ID {snapshot_id} while publishing COW
- bounded compaction is not supported for copy-on-write tasks
- Data file should not in task deletes
- Manual iceberg compaction task {} for sink {} failed: {}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/698a0606d6308447.
Report an issue: GitHub.