risingwavelabs/risingwave · error · StreamExecutorError
ExchangeChannelClosed
Error message
ExchangeChannelClosed
What it means
The ExchangeChannelClosed variant transparently wraps exchange::error::ExchangeChannelClosed. It is thrown when the exchange layer's data channel between actors (the network path moving stream chunks/barriers between compute nodes) is found closed. It uses #[from] so any ExchangeChannelClosed propagates automatically into StreamExecutorError.
Source
Thrown at src/stream/src/executor/error.rs:88
#[error("Sink error: sink_id={1}, error: {0}")]
SinkError(
#[source]
#[backtrace]
SinkError,
SinkId,
),
#[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(View on GitHub (pinned to 6469eb736d)
Solutions
- Inspect the wrapped ExchangeChannelClosed for which actor/channel closed.
- Check the remote compute node's logs for the original failure (crash, panic, graceful stop).
- Let the framework's failover restart affected actors and re-establish channels.
- If recurring, check network stability and node resource limits between compute nodes.
Defensive patterns
Strategy: try-catch
Validate before calling
// monitor exchange peer availability
if !actor_manager.is_actor_alive(peer_actor_id) {
tracing::warn!("exchange peer actor {} not alive", peer_actor_id);
} Type guard
fn is_exchange_closed(e: &StreamExecutorError) -> bool {
e.variant_name() == "ExchangeChannelClosed"
} Try / catch
match res {
Err(e) if e.variant_name() == "ExchangeChannelClosed" => {
// remote actor/node terminated; rely on actor restart/failover
}
other => other?,
} Prevention
- Monitor compute node liveness between which exchange channels exist.
- Treat any channel-closed as a symptom; find the root peer failure first.
- Keep networks between compute nodes stable (no idle-connection killing LBs).
- Enable structured logs on exchange send/recv failures for triage.
When it happens
Trigger: Produced by `?` on exchange send/recv operations in the exchange layer, wrapped here via From<ExchangeChannelClosed>. Happens when the remote endpoint of an inter-node/inter-actor exchange channel is closed.
Common situations: Remote compute node crashed or was killed; network disconnect during data exchange; actor terminated due to a fatal error upstream of the exchange.
Related errors
- broken broadcast_channel
- channel closed
- RpcError
- Channel closed: {0}
- failed to send the rebuild-sink request to the reader
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/4bb7565489c3d463.
Report an issue: GitHub.