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

  1. Compare the two printed barriers (epochs and variants) to identify the divergence point.
  2. Check meta node barrier injection logs for skipped or duplicated epochs.
  3. Look for actor restarts around that epoch that may have missed barriers.
  4. 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

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


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