linera-io/linera-protocol · error · ExporterError

BadInitialization

BadInitialization

Error message

ExporterError::BadInitialization

What it means

The Linera exporter learns new chains only from their very first block. ExporterState::initialize_chain registers a chain from its initial block and enforces block.height == BlockHeight::ZERO; BadInitialization here means you tried to register a chain starting from a block at height greater than zero.

Source

Thrown at linera-exporter/src/state.rs:119

                .map_err(|e| ExporterError::GenericError(e.into()))?;
            if block.height == expected_block_height {
                *last_processed = block.into();
                return Ok(true);
            }
            tracing::warn!(
                ?expected_block_height,
                ?block,
                "attempted to index a block out of order",
            );
            Ok(false)
        } else {
            Err(ExporterError::UnprocessedChain)
        }
    }

    /// Registers a chain from its initial block at height zero.
    pub async fn initialize_chain(&mut self, block: BlockId) -> Result<(), ExporterError> {
        ensure!(
            block.height == BlockHeight::ZERO,
            ExporterError::BadInitialization
        );

        if self.chain_states.contains_key(&block.chain_id).await? {
            Err(ExporterError::ChainAlreadyExists(block.chain_id))?
        }

        let chain_id = block.chain_id;
        self.chain_states.insert(&chain_id, block.into())?;
        Ok(())
    }

    /// Returns the highest block already processed for the given chain, if any.
    pub async fn get_chain_status(
        &self,
        chain_id: &ChainId,
    ) -> Result<Option<LiteBlockId>, ExporterError> {

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Point the exporter at the chain's height-0 block (start export from the beginning of the chain)
  2. Make sure the exporter's source node can serve block 0 for every chain it registers
  3. If starting mid-chain is intentional, pre-register the chain in the exporter state first and then index the later blocks — never route a non-zero height into initialize_chain

Example fix

// before
exporter_state.initialize_chain(block_id).await?; // BadInitialization when height > 0

// after
if block_id.height == BlockHeight::ZERO {
    exporter_state.initialize_chain(block_id).await?;
} else {
    // chain must already be registered; index the block instead
    exporter_storage.index_block(block_id).await?;
}
Defensive patterns

Strategy: validation

Validate before calling

use linera_base::identifiers::BlockHeight;

// before registering a chain in the exporter:
if block_id.height != BlockHeight::ZERO {
    anyhow::bail!("initialize_chain requires the height-0 block, got height {}", block_id.height);
}

Prevention

When it happens

Trigger: Calling initialize_chain (directly or through the storage layer's indexing path) with a BlockId whose height is not zero — e.g. an exporter that starts indexing a chain from a later block because it never observed the height-0 block.

Common situations: Exporter pointed at an already-running network so the first block it sees for a chain is not block 0; exporter configured to start from a non-zero height; genesis/early blocks pruned from the source storage.

Related errors


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