FuelLabs/fuel-core · error

on-chain database doesn't have height

Error message

on-chain database doesn't have height

What it means

CombinedDatabase::rollback_to walks the on-chain, off-chain, gas-price and compression databases back to a target block height. It first reads each database's latest height from its metadata column; the on-chain database returning None (no height ever recorded) is fatal because there is nothing to roll back and no baseline to compare against. This means the on-chain database never committed even the genesis block.

Source

Thrown at crates/fuel-core/src/combined_database.rs:473

            )))?;

        Ok(state_config)
    }

    /// Rollbacks the state of the blockchain to a specific block height.
    pub fn rollback_to<S>(
        &mut self,
        target_block_height: BlockHeight,
        shutdown_listener: &mut S,
    ) -> anyhow::Result<()>
    where
        S: ShutdownListener,
    {
        while !shutdown_listener.is_cancelled() {
            let on_chain_height = self
                .on_chain()
                .latest_height_from_metadata()?
                .ok_or(anyhow::anyhow!("on-chain database doesn't have height"))?;

            let off_chain_height = self
                .off_chain()
                .latest_height_from_metadata()?
                .ok_or(anyhow::anyhow!("off-chain database doesn't have height"))?;

            let gas_price_chain_height =
                self.gas_price().latest_height_from_metadata()?;
            let gas_price_rolled_back = is_equal_or_less_than_or_none(
                gas_price_chain_height,
                target_block_height,
            );

            let compression_db_height =
                self.compression().latest_height_from_metadata()?;
            let compression_db_rolled_back =
                is_equal_or_less_than_or_none(compression_db_height, target_block_height);

View on GitHub (pinned to b9d4d170da)

Solutions

  1. Start the node normally once so genesis (and at least one block) is committed, then retry the rollback.
  2. Verify the database path/configuration points at the intended, initialized chain database.
  3. If metadata is corrupted, restore from a healthy snapshot or re-sync from scratch.
  4. Check disk space and permissions — a failed initial commit can leave the DB without height metadata.
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every component database has a height before rolling back.
for name in ["on-chain", "off-chain"] {
    let h = match name {
        "on-chain" => combined_db.on_chain().latest_height_from_metadata()?,
        _ => combined_db.off_chain().latest_height_from_metadata()?,
    };
    if h.is_none() {
        anyhow::bail!("{} database is not initialized; import genesis first", name);
    }
}

Try / catch

match combined_db.rollback_to(target, &mut shutdown) {
    Ok(()) => Ok(()),
    Err(e) if e.to_string().contains("doesn't have height") => {
        // DB empty: initialize by running the node once, then retry
        initialize_db_then_retry()
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling rollback_to (startup re-org realignment, --rolling/re-org tooling, snapshot restore flows) on an on-chain database whose metadata column has no height — a freshly created or wiped database.

Common situations: Running rollback tooling against a brand-new DB before genesis import; wrong --db-path pointing at an empty directory; metadata column deleted or corrupted; restoring a partial snapshot that omits on-chain metadata.

Related errors


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