FuelLabs/fuel-core · error

No block height found

Error message

No block height found

What it means

When reading a parquet-encoded snapshot table, Reader::read_config takes the first row group from the decoder, whose first row carries the block height and config payload. If the decoder yields no row group at all, reading fails with 'No block height found' (crates/chain-config/src/config/state/reader.rs:208). In practice the file exists but is empty or header-only — a table that was created but never written, or truncated.

Source

Thrown at crates/chain-config/src/config/state/reader.rs:208

            data_source: DataSource::Parquet {
                tables,
                latest_block_config,
            },
            chain_config,
        })
    }

    #[cfg(feature = "parquet")]
    fn read_config<Config>(path: &std::path::Path) -> anyhow::Result<Config>
    where
        Config: serde::de::DeserializeOwned,
    {
        use super::parquet::decode::Decoder;

        let file = std::fs::File::open(path)?;
        let group = Decoder::new(file)?
            .next()
            .ok_or_else(|| anyhow::anyhow!("No block height found"))??;
        let config = group
            .into_iter()
            .next()
            .ok_or_else(|| anyhow::anyhow!("No config found"))?;
        postcard::from_bytes(&config).map_err(Into::into)
    }

    #[cfg(feature = "std")]
    pub fn open(
        snapshot_metadata: crate::config::SnapshotMetadata,
    ) -> anyhow::Result<Self> {
        Self::open_w_config(snapshot_metadata, MAX_GROUP_SIZE)
    }

    #[cfg(feature = "std")]
    pub fn open_w_config(
        snapshot_metadata: crate::config::SnapshotMetadata,
        json_group_size: usize,

View on GitHub (pinned to b9d4d170da)

Solutions

  1. Regenerate the snapshot end-to-end, letting the writer finish and close all row groups.
  2. Before opening, verify each table file is non-empty and plausibly sized.
  3. Check that SnapshotMetadata (directory + table list) matches the files actually on disk.
  4. If generating snapshots programmatically, ensure the writer's close() runs even on early exits.

Example fix

// before — fails with 'No block height found' on an empty table
let reader = StateReader::open(snapshot_metadata)?;

// after — guard against empty/truncated tables first
for table in &expected_tables {
    let path = snapshot_dir.join(table);
    let len = std::fs::metadata(&path)
        .with_context(|| format!("missing snapshot table {path:?}"))?
        .len();
    anyhow::ensure!(len > 0, "snapshot table {table} is empty ({len} bytes)");
}
Defensive patterns

Strategy: validation

Validate before calling

// Reject empty/truncated table files before opening the reader
for table in &expected_tables {
    let path = snapshot_dir.join(table);
    let len = std::fs::metadata(&path)
        .with_context(|| format!("missing snapshot table {path:?}"))?
        .len();
    anyhow::ensure!(len > 0, "snapshot table {table} is empty ({len} bytes)");
}

Try / catch

match StateReader::open(snapshot_metadata) {
    Err(e) if e.to_string().contains("No block height found") => {
        // a table parquet file is empty/header-only → regenerate the snapshot
        regenerate_snapshot().await?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: StateReader::open / open_w_config (or read_config directly) on a snapshot directory where a table's parquet file is 0 bytes or contains zero row groups.

Common situations: Interrupted snapshot generation (process killed mid-write, writer's close() never ran); copying a snapshot and missing file contents; pointing SnapshotMetadata at the wrong directory whose expected tables were never produced; filesystem truncation.

Related errors


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