risingwavelabs/risingwave · error · anyhow::Error
reschedule failed
Error message
reschedule failed
What it means
The reschedule command submitted a fragment reschedule plan to the meta service but the reported success flag was false, so the command aborts with this error after printing the current plan revision.
Solutions
- Re-run the reschedule with the current plan revision (fetch the latest revision first)
- Adjust the plan to reference existing worker ids and valid fragment ids
- Retry after the cluster stabilizes if a concurrent failover invalidated the plan
Defensive patterns
Strategy: retry
Validate before calling
let latest = get_current_revision(&meta).await?;
if plan_revision != latest {
return Err(anyhow!("stale plan revision {} != {}", plan_revision, latest));
} Prevention
- Fetch the latest revision immediately before rescheduling
- Re-fetch worker/fragment state after cluster topology changes
- Retry reschedule with a fresh plan after failures
When it happens
Trigger: Running `risectl meta reschedule` with a plan that conflicts with the cluster's current revision, or a plan the meta service rejects (e.g. moving actors for a worker that no longer exists).
Common situations: Cluster topology changed between composing the plan and applying it (node failure/scale-down); stale revision from a previous reschedule; invalid worker ids in the plan.
Related errors
- duplicate worker id in plan, prev ->
- cannot find StreamActor of actor
- concurrent backup job is not supported: existent job
- `debug_splits` is not allowed in release mode
- downstream relation missing for
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/2a0d4be7cf0afb71.
Report an issue: GitHub.
Appendix: source
Thrown at src/ctl/src/cmd_impl/meta/reschedule.rs:132
println!("\tChange: {:?}", reschedule.get_worker_actor_diff());
}
println!();
}
if !dry_run {
println!("---------------------------");
let (success, revision) = meta_client
.reschedule(reschedules, revision, resolve_no_shuffle)
.await?;
if !success {
println!(
"Reschedule failed, please check the plan or the revision, current revision is {}",
revision
);
return Err(anyhow!("reschedule failed"));
}
println!("Reschedule success, current revision is {}", revision);
}
Ok(())
}
// It will match formats like `1:[1:+1,2:-1,3:1];2:[1:1,2:1]`, indicating which workers' actors need to change in quantity for each fragment.
fn parse_plan(mut plan: String) -> Result<HashMap<u32, PbWorkerReschedule>> {
let mut reschedules = HashMap::new();
let regex = Regex::new(r"^(\d+):\[((?:\d+:[+-]?\d+,?)+)]$")?;
plan.retain(|c| !c.is_whitespace());
for fragment_reschedule_plan in plan.split(';') {
if fragment_reschedule_plan.is_empty() {
continue;
}View on GitHub (pinned to 6469eb736d)