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
- Regenerate the snapshot end-to-end, letting the writer finish and close all row groups.
- Before opening, verify each table file is non-empty and plausibly sized.
- Check that SnapshotMetadata (directory + table list) matches the files actually on disk.
- 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
- Let snapshot generation run to completion; a killed writer leaves header-only files.
- Always call the writer's close()/finalize before using a snapshot.
- Validate file sizes against the metadata before opening a reader.
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
- No config found
- Missing code for contract: {id}
- Missing utxo for contract: {id}
- Missing column. Check the schema!
- Fragments use different compressions.
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/5af6d3fa61c87d3c.
Report an issue: GitHub.