linera-io/linera-protocol · critical
Linera scan loop exited unexpectedly: {result:?}
Error message
Linera scan loop exited unexpectedly: {result:?} What it means
In serve_loop's tokio::select!, the Linera scan loop task exited. This loop watches the bridge's own Linera chain for BurnEvents so withdrawals are relayed to the EVM side; if it dies (error return or panic), serve_loop fails fast because withdrawals would strand.
Source
Thrown at linera-bridge/src/relay/mod.rs:511
// stream hiccup), and a missed `NewIncomingBundle` would otherwise strand
// its messages until the next one. Reuse the monitor's scan interval as the
// drain cadence; an empty inbox makes `process_inbox` a cheap no-op.
let mut inbox_drain_interval = tokio::time::interval(monitor_scan_interval);
// Consume the immediate first tick — the startup drain above already ran.
inbox_drain_interval.tick().await;
// ── Main loop: process chain operations + notifications ──
tracing::info!("Listening for chain operations and notifications...");
loop {
tokio::select! {
result = &mut chain_listener_handle => {
anyhow::bail!("Chain listener exited unexpectedly: {result:?}");
}
result = &mut evm_scan_handle => {
anyhow::bail!("EVM scan loop exited unexpectedly: {result:?}");
}
result = &mut linera_scan_handle => {
anyhow::bail!("Linera scan loop exited unexpectedly: {result:?}");
}
result = &mut retry_handle => {
anyhow::bail!("Retry loop exited unexpectedly: {result:?}");
}
result = &mut http_server_handle => {
anyhow::bail!("HTTP server exited unexpectedly: {result:?}");
}
result = &mut admin_server_handle => {
anyhow::bail!("Admin HTTP server exited unexpectedly: {result:?}");
}
_ = inbox_drain_interval.tick() => {
// Periodic safety net for a missed `NewIncomingBundle`: sync and
// drain the inbox so stranded messages (e.g. user burns) are
// eventually processed even without a fresh notification.
if let Err(e) = chain_client.synchronize_from_validators().await {
tracing::warn!("Periodic sync before inbox drain failed: {e}");
} else {
match chain_client.process_inbox().await {View on GitHub (pinned to 6c226ddcb3)
Solutions
- Inspect relay logs for the Linera scan task's final error (it logs before exiting) — that is the root cause, this bail is only the propagation.
- Restore connectivity/authorization to the Linera validators, then restart the relay.
- If it was a panic decoding block events, fix the decoder for the new event shape and redeploy.
- Run the relay under a supervisor (systemd Restart=always, docker restart policy) since serve_loop intentionally exits on any task death.
Example fix
// before
result = &mut linera_scan_handle => {
anyhow::bail!("Linera scan loop exited unexpectedly: {result:?}");
}
// after: include the outcome kind in the fatal error
result = &mut linera_scan_handle => {
let kind = match &result { Ok(()) => "returned", Err(j) if j.is_panic() => "panicked", Err(_) => "aborted" };
anyhow::bail!("Linera scan loop {kind}: {result:?}; see prior scan-loop logs for root cause");
} Defensive patterns
Strategy: retry
Validate before calling
// Before serving: one successful sync proves Linera connectivity/authorization chain_client.synchronize_from_validators().await?;
Try / catch
// Fatal by design; restart the relay process. Log the scan task's last error for diagnosis.
Prevention
- Keep validator endpoints stable and the client key authorized on the bridge chain.
- Make event decoding defensive (skip + log unknown shapes) so one bad block cannot kill the scan loop.
When it happens
Trigger: The Linera scan future returns Err after exhausting its retries (chain client cannot synchronize with validators, chain query failures) or panics while parsing block events; the task is also prodded by scan_notify on every new block notification, so notification-driven code paths run inside it.
Common situations: Validators unreachable for an extended period; the bridge chain's client key not authorized (multisig leader changed); a malformed/unexpected event in a block after an application upgrade panics the decoder.
Related errors
- Chain listener exited unexpectedly: {result:?}
- EVM scan loop exited unexpectedly: {result:?}
- Retry loop exited unexpectedly: {result:?}
- HTTP server exited unexpectedly: {result:?}
- Admin HTTP server exited unexpectedly: {result:?}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/554eb734ec2fd0f8.
Report an issue: GitHub.