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

  1. Retry the compaction — if the planner intermittently split the plan, a fresh planning round may yield a single plan.
  2. Reduce compaction scope (e.g. run Full COW compaction on smaller tables/partitions) so a single table-scoped plan suffices.
  3. 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.
  4. 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

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


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/698a0606d6308447. Report an issue: GitHub.