linera-io/linera-protocol · error · ChainError

Cannot confirm a block before its predecessors: {current_blo

Error message

Cannot confirm a block before its predecessors: {current_block_height:?}

What it means

ChainTipState::already_validated_block (linera-chain/src/chain.rs:429-437) errors with MissingEarlierBlocks when a certificate's height is strictly above the chain's next_block_height — the chain is missing one or more predecessor blocks, so the certificate cannot be processed yet. It is the gatekeeper for process_timeout (linera-core/src/chain_worker/state.rs:793) and process_validated_block (state.rs:892), both of which must receive certificates in height order. This is a synchronization error, not a permanent rejection: once the gap is filled, the same certificate will process.

Source

Thrown at linera-chain/src/chain.rs:430

    pub fn verify_block_chaining(&self, new_block: &ProposedBlock) -> Result<(), ChainError> {
        ensure!(
            new_block.height == self.next_block_height,
            ChainError::UnexpectedBlockHeight {
                expected_block_height: self.next_block_height,
                found_block_height: new_block.height
            }
        );
        ensure!(
            new_block.previous_block_hash == self.block_hash,
            ChainError::UnexpectedPreviousBlockHash
        );
        Ok(())
    }

    /// Returns `true` if the validated block's height is below the tip height. Returns an error if
    /// it is higher than the tip.
    pub fn already_validated_block(&self, height: BlockHeight) -> Result<bool, ChainError> {
        ensure!(
            self.next_block_height >= height,
            ChainError::MissingEarlierBlocks {
                current_block_height: self.next_block_height,
            }
        );
        Ok(self.next_block_height > height)
    }
}

impl<C> ChainStateView<C>
where
    C: Context + Clone + 'static,
    C::Extra: ExecutionRuntimeContext,
{
    /// Returns the [`ChainId`] of the chain this [`ChainStateView`] represents.
    pub fn chain_id(&self) -> ChainId {
        self.context().extra().chain_id()
    }

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Fetch and process the missing confirmed blocks (query the sender chain or peer validators) up to the certificate's height, then resubmit the certificate
  2. Ensure your delivery layer processes blocks in height order per chain
  3. Retry the same certificate after synchronization — it is not poisoned
  4. If a node persistently lags, check its storage health and catch it up via a full chain query

Example fix

// before: submitting the certificate directly
worker.handle_validated_certificate(cert).await?;

// after: fill the gap first, then retry
let tip = chain_info.next_block_height;
if cert.block().header.height > tip {
    for h in tip..cert.block().header.height {
        let missing = fetch_confirmed_block(chain_id, h).await?;
        worker.handle_confirmed_certificate(missing).await?;
    }
}
worker.handle_validated_certificate(cert).await?;
Defensive patterns

Strategy: retry

Validate before calling

// Before submitting a certificate, check the chain can anchor it:
let next = chain_info.next_block_height;
if cert_height > next {
    // gap: process confirmed blocks [next, cert_height) first
    for h in next..cert_height {
        let block = fetch_confirmed_block(chain_id, h).await?;
        worker.handle_confirmed_block(block).await?;
    }
}

Try / catch

match worker.handle_certificate(cert).await {
    Err(WorkerError::ChainError(ChainError::MissingEarlierBlocks { current_block_height })) => {
        // sync missing heights (current_block_height..cert height), then retry the SAME certificate
    }
    other => other?,
}

Prevention

When it happens

Trigger: Delivering a ValidatedBlockCertificate or TimeoutCertificate for height 10 while the local chain state is at next_block_height 7; a validator that skipped/restarted and lost heights receiving current certificates; cross-chain message handling that delivers a recipient update before the sender's earlier blocks were processed.

Common situations: Validators lagging behind the leader and receiving newer certificates first; network reordering; client submitting a higher block without first syncing handle_confirmed_block for the missing heights; storage restored from an old snapshot.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/9b12d10ff341a268. Report an issue: GitHub.