risingwavelabs/risingwave · error · StreamExecutorError
Failed to align barrier: expected `{0:?}` but got `{1:?}`
Error message
Failed to align barrier: expected `{0:?}` but got `{1:?}` What it means
The AlignBarrier variant is thrown when a barrier executor receives a barrier that does not match the one it is currently expecting during barrier alignment. The message shows both barriers: expected `{0:?}` but got `{1:?}`. Barrier alignment guarantees all actors process the same barriers in the same order; a mismatch means the epoch/stream ordering is broken.
Source
Thrown at src/stream/src/executor/error.rs:95
#[error(transparent)]
RpcError(
#[from]
#[backtrace]
RpcError,
),
#[error("Channel closed: {0}")]
ChannelClosed(String),
#[error(transparent)]
ExchangeChannelClosed(
#[from]
#[backtrace]
ExchangeChannelClosed,
),
#[error("Failed to align barrier: expected `{0:?}` but got `{1:?}`")]
AlignBarrier(Box<Barrier>, Box<Barrier>),
#[error("Connector error: {0}")]
ConnectorError(
#[source]
#[backtrace]
BoxedError,
),
#[error(transparent)]
DmlError(
#[from]
#[backtrace]
DmlError,
),
#[error(transparent)]
NotImplemented(#[from] NotImplemented),View on GitHub (pinned to 6469eb736d)
Solutions
- Compare the two printed barriers (epochs and variants) to identify the divergence point.
- Check meta node barrier injection logs for skipped or duplicated epochs.
- Look for actor restarts around that epoch that may have missed barriers.
- File an issue with the full error (both barriers) if reproducible — this usually indicates an internal invariant violation rather than user error.
Defensive patterns
Strategy: type-guard
Validate before calling
// before processing, assert barrier epoch continuity
debug_assert_eq!(incoming.epoch, expected.epoch, "barrier epoch mismatch");
if incoming.epoch != expected.epoch {
tracing::error!(expected = ?expected, got = ?incoming, "barrier misalignment");
} Type guard
fn is_align_barrier_error(e: &StreamExecutorError) -> bool {
e.variant_name() == "AlignBarrier"
} Try / catch
if let Err(e) = res {
if e.variant_name() == "AlignBarrier" {
// log both barriers (expected vs got) and trigger actor failover
tracing::error!(error = ?e, "barrier alignment failed; failing over");
return Err(e);
}
return Err(e);
} Prevention
- Keep meta barrier injection single-threaded and ordered per actor.
- Avoid restarting actors mid-epoch without barrier recovery.
- Upgrade together with fixes to barrier dispatch races.
- Capture both barrier payloads when reporting this error.
When it happens
Trigger: During BarrierAlignExecutor processing, when the incoming barrier's epoch (or type, e.g. checkpoint vs config-change) differs from the expected barrier: expected={:?} got={:?}. Constructed with two boxed Barrier values.
Common situations: Bugs or races in barrier injection/dispatch from the meta node; actor restarted mid-stream and missed a barrier; corrupted or reordered message delivery in the exchange layer.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- compaction resolver sink {} task {} missing resolver task in
- compaction resolver sink {} expected initial begin barrier,
- compaction resolver sink {} task {} expected end barrier, go
- Exchange executor should not have children!
- Iceberg metadata scan received a non-Iceberg connector
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/54161c2a13ba7edb.
Report an issue: GitHub.