FuelLabs/fuel-core · error · anyhow::Error

Block not found at height: {:?}

Error message

Block not found at height: {:?}

What it means

Thrown by CompressionBlockDBAdapter::get_block (crates/fuel-core/src/service/adapters/compression_adapters.rs:73), the BlockSource port of the DA compression service. After resolving the requested BlockAt against the latest on-chain view, get_sealed_block_by_height returned None: no sealed block is stored at that height. Genesis resolution is a separate branch with its own error, so this specifically covers missing blocks at explicit heights.

Source

Thrown at crates/fuel-core/src/service/adapters/compression_adapters.rs:73

}

impl block_source::BlockSource for CompressionBlockDBAdapter {
    fn subscribe(&self) -> fuel_core_services::stream::BoxStream<SharedImportResult> {
        self.block_importer.events_shared_result()
    }

    fn get_block(&self, height: BlockAt) -> anyhow::Result<Block> {
        let latest_view = self.db.latest_view()?;
        let height = match height {
            BlockAt::Genesis => latest_view.genesis_height()?.ok_or_else(|| {
                anyhow::anyhow!("Genesis block not found in the database")
            })?,
            BlockAt::Specific(h) => h.into(),
        };
        let block = latest_view
            .get_sealed_block_by_height(&height)?
            .map(|sealed_block| sealed_block.entity)
            .ok_or(anyhow::anyhow!("Block not found at height: {:?}", height))?;
        Ok(block)
    }
}

impl configuration::CompressionConfigProvider
    for crate::service::config::DaCompressionConfig
{
    fn config(&self, chain_id: ChainId) -> config::CompressionConfig {
        config::CompressionConfig::new(
            self.retention_duration,
            self.starting_height,
            self.metrics,
            chain_id,
        )
    }
}

impl compression_storage::LatestHeight for Database<CompressionDatabase> {

View on GitHub (pinned to b9d4d170da)

Solutions

  1. Set the compression starting_height to a height at or below the node's current chain height with unpruned history
  2. Wait until the node has fully synced past starting_height before enabling DA compression
  3. If history was pruned, re-sync the on-chain database or restore it from a full snapshot

Example fix

// before (config):
//   da_compression: { starting_height: 1_000_000, .. }   // chain only at 900_000
// after:
//   da_compression: { starting_height: 900_000, .. }      // <= latest committed height
Defensive patterns

Strategy: validation

Validate before calling

fn can_serve(db: &Database<OnChain>, h: u32) -> anyhow::Result<bool> {
    let view = db.latest_view()?;
    let latest = view.latest_height().map(u32::from);
    Ok(matches!(latest, Some(l) if h <= l)
        && view.get_sealed_block_by_height(&h.into()).is_ok())
}
// call before BlockSource::get_block(BlockAt::Specific(h))

Type guard

fn is_block_not_found(e: &anyhow::Error) -> bool {
    e.to_string().starts_with("Block not found at height")
}

Try / catch

match block_source.get_block(BlockAt::Specific(h)) {
    Err(e) if is_block_not_found(&e) => {
        // height beyond chain/pruned: skip or wait for sync, not a fatal error
        tracing::warn!(h, "block not available yet");
    }
    other => other,
}

Prevention

When it happens

Trigger: The compression service calls get_block(BlockAt::Specific(h)) where h is above the latest committed height, inside a pruned range, or in a gap (e.g., after rollback) of Database<OnChain>.

Common situations: DaCompressionConfig starting_height set beyond current chain height or beyond retained history; enabling compression on a node that has not synced that far; querying right after the database was rolled back to a lower height.

Related errors


AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16). Data as JSON: /api/errors/7c6bbcd5e6e7d999. Report an issue: GitHub.