linera-io/linera-protocol · error · NodeError
Events not found: {0:?}
Error message
Events not found: {0:?} What it means
Raised in RemoteNodeUpdater::send_block_proposal when a validator rejects a proposal with EventsNotFound: the client maps each missing event to its publishing chain, forwards those chains' certificates to the validator, and retries — but only for publisher chains it has not already sent. If the same EventsNotFound comes back and every publisher chain is already in publisher_chain_ids_sent, there is nothing new to forward: the local node itself cannot provide those events, so the error is surfaced with the original event IDs.
Source
Thrown at linera-core/src/updater.rs:665
self.send_chain_info_up_to_heights(
origin_heights,
CrossChainMessageDelivery::Blocking,
)
.await?;
}
Err(NodeError::EventsNotFound(event_ids)) => {
let mut publisher_heights = BTreeMap::new();
let chain_ids = event_ids
.iter()
.map(|event_id| event_id.chain_id)
.filter(|chain_id| !publisher_chain_ids_sent.contains(chain_id))
.collect::<BTreeSet<_>>();
tracing::debug!(
remote_node = self.remote_node.address(),
?chain_ids,
"missing events; sending chains to validator",
);
ensure!(!chain_ids.is_empty(), NodeError::EventsNotFound(event_ids));
for chain_id in chain_ids {
let height = self
.local_node
.get_next_height_to_preprocess(chain_id)
.await?;
publisher_heights.insert(chain_id, height);
publisher_chain_ids_sent.insert(chain_id);
}
self.send_chain_info_up_to_heights(
publisher_heights,
CrossChainMessageDelivery::NonBlocking,
)
.await?;
}
Err(error @ NodeError::ChainError { .. }) => {
// The validator rejected the proposal because of its local chain
// manager state — most commonly an incompatible confirmed vote tied
// to a locking block we don't yet have. The caller should pullView on GitHub (pinned to 6c226ddcb3)
Solutions
- Before proposing, run download_certificates on every publisher chain referenced by the block (the event IDs in the error tell you which chains) so the local node holds the events
- Use prepare_chain()/full chain sync so epoch and admin-chain events are available locally
- Retry after syncing: once local storage has the events, forwarding them to the validator succeeds
- If the events genuinely do not exist (e.g. wrong stream/index), fix the application's referenced stream indices
Defensive patterns
Strategy: retry
Validate before calling
// Before proposing, make sure the local node holds every publisher chain your block reads.
for publisher in block_publisher_chains(&block) {
let local = client.local_node().chain_info(publisher).await?;
// ensure local height covers the events your application references
assert!(local.next_block_height > required_height[publisher]);
} Type guard
fn events_not_found(err: &chain_client::Error) -> Option<&Vec<EventId>> {
match err {
chain_client::Error::RemoteNodeError(NodeError::EventsNotFound(ids)) => Some(ids),
_ => None,
}
} Try / catch
match client.process_pending_block().await {
Err(e) if let Some(ids) = events_not_found(&e) => {
// ids tell you the publisher chains; download them, then retry.
for chain in ids.iter().map(|id| id.chain_id).collect::<BTreeSet<_>>() {
client.synchronize_chain_state_from_all_validators_for(chain).await?;
}
client.process_pending_block().await
}
other => other,
} Prevention
- Subscribe-and-propose workflows: always sync publisher chains up to the events your block consumes first
- Validate stream indices your application references exist on the publisher chain before building the block
- Treat the event IDs in this error as actionable data: they name exactly which chains to fetch
When it happens
Trigger: The block being proposed reads events (streams, epoch events) from publisher chains whose certificates the local node does not hold; event streams referenced by an application whose publishing chain was never synced locally; validator needing admin-chain epoch events the client lacks.
Common situations: Applications subscribing to streams on other chains after a wallet restore; multi-chain apps where the destination client only has message bundles but not the full publisher history; validators requiring committee/epoch events the client never downloaded.
Related errors
- Cannot vote for block proposal of chain {chain_id} because {
- Checkpoint precondition failed: chain has consumed system ev
- Local error handling validator response: validator still rep
- StreamNameTooLong
- Cannot confirm a block before its predecessors: {current_blo
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/99a5aa478362208f.
Report an issue: GitHub.