risingwavelabs/risingwave · error · MetaError
failed to align vnode count for table {}({}): required {}, b
Error message
failed to align vnode count for table {}({}): required {}, but got {} What it means
While building the stream graph, the meta service aligns each table's vnode count across fragments and stores it as `maybe_vnode_count`. If the computed/required vnode count cannot be aligned (e.g. incompatible distributions between fragments of the same table), the deferred error is surfaced with the table name, id, required and actual counts. This prevents actors with inconsistent parallelism from being deployed.
Source
Thrown at src/meta/src/stream/stream_graph/actor.rs:510
match table.vnode_count_inner().value_opt() {
// Vnode count of this table is not set to placeholder, meaning that we are replacing
// a streaming job, and the existing state table requires a specific vnode count.
// Check if it's the same with what we derived from the schedule result.
//
// Typically, inconsistency should not happen as we force to align the vnode count
// when planning the new streaming job in the frontend.
Some(required_vnode_count) if required_vnode_count != vnode_count => {
error = Some(format!(
"failed to align vnode count for table {}({}): required {}, but got {}",
table.id, table.name, required_vnode_count, vnode_count
));
}
// Normal cases.
_ => table.maybe_vnode_count = VnodeCount::set(vnode_count).to_protobuf(),
}
});
if let Some(error) = error {
bail!(error);
}
}
Ok(Self {
distributions,
fragment_graph,
})
}
/// Build a stream graph by duplicating each fragment as parallel actors. Returns
/// [`ActorGraphBuildResult`] that will be further used to build actors on the compute nodes.
pub fn generate_graph(self) -> MetaResult<ActorGraphBuildResult> {
// Build the actor graph and get the final state.
let ActorGraphBuildStateInner {
fragment_actor_builders,
downstream_fragment_changes,
upstream_fragment_changes,
} = self.build_actor_graph()?;View on GitHub (pinned to 6469eb736d)
Solutions
- Read the message's table name/id and required-vs-got counts; align the table's vnode count with the required value (e.g. recreate the MV with matching parallelism).
- Check the upstream/upstream-derived fragments for explicit vnode-count or parallelism settings that conflict with the target table.
- If this happens after a version upgrade, recreate the affected streaming job so vnode counts are recomputed consistently.
- Verify any `vnode_count` overrides in table properties and remove conflicting ones.
Example fix
// before CREATE MATERIALIZED VIEW mv AS SELECT ... FROM t; -- t has vnode_count 32, plan requires 64 // after ALTER TABLE t SET PARALLELISM = 64; CREATE MATERIALIZED VIEW mv AS SELECT ... FROM t;
Defensive patterns
Strategy: validation
Validate before calling
// SQL: verify table parallelism/vnode settings match requirements before creating dependents SHOW PARAMETERS FOR TABLE t; -- check parallelism / vnode related settings
Try / catch
// Rust: the builder defers this error
match StreamGraphBuilder::new(...) {
Ok(builder) => builder,
Err(e) if e.to_string().contains("failed to align vnode count") => {
// retry with corrected parallelism or surface actionable error to user
return Err(anyhow::anyhow!("adjust table vnode/parallelism: {e:#}"));
}
Err(e) => return Err(e),
} Prevention
- Keep parallelism settings of tables consistent with downstream MVs that read them.
- Avoid overriding vnode_count unless you understand fragment distribution alignment.
- After upgrades, recreate jobs that report vnode misalignment rather than editing internals.
When it happens
Trigger: Creating or altering a materialized view/table where fragments derived from the same table end up with different vnode counts; calling the graph builder `new` (actor.rs:510 region) with a fragment graph whose table vnode counts conflict (required N, got M).
Common situations: Changing parallelism (`ALTER ... SET PARALLELISM`) on an object that participates in multiple fragments; restoring/migrating graphs across versions with different vnode-count defaults; custom vnode count settings conflicting with upstream fragment distributions.
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
- invalid parallelism
- cannot use a different max parallelism when replacing stream
- duplicate vnode {:?}. request vnode: {:?}, prev vnode: {:?}.
- empty vnode bitmap
- there should be no ExchangeNode on the top of the plan node:
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/d6b582d06a4dde89.
Report an issue: GitHub.