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

Historical execution is only supported with RocksDB

Error message

Historical execution is only supported with RocksDB

What it means

Validated while assembling the node's sub-services: enabling config.historical_execution requires a RocksDB backend because historical (view-at-height) execution relies on RocksDB versioned columns. If combined_db_config.database_type is anything other than DbType::RocksDb (i.e. InMemory), startup fails fast with this error before any service starts.

Source

Thrown at crates/fuel-core/src/service/sub_services.rs:165

    let (preconfirmation_sender, preconfirmation_receiver) =
        tokio::sync::mpsc::channel(1024);
    #[cfg(not(feature = "p2p"))]
    let (preconfirmation_sender, _) = tokio::sync::mpsc::channel(1024);

    let genesis_block = on_chain_view
        .genesis_block()?
        .unwrap_or(create_genesis_block(config).compress(&chain_id));
    let last_block_header = on_chain_view
        .get_current_block()?
        .map(|block| block.header().clone())
        .unwrap_or(genesis_block.header().clone());

    let last_height = *last_block_header.height();

    if config.historical_execution
        && config.combined_db_config.database_type != DbType::RocksDb
    {
        return Err(anyhow::anyhow!(
            "Historical execution is only supported with RocksDB"
        ));
    }

    #[cfg(feature = "p2p")]
    let p2p_externals = config
        .p2p
        .clone()
        .map(fuel_core_p2p::service::build_shared_state);

    #[cfg(feature = "p2p")]
    let p2p_adapter = {
        use crate::service::adapters::PeerReportConfig;

        // Hardcoded for now, but left here to be configurable in the future.
        // TODO: https://github.com/FuelLabs/fuel-core/issues/1340
        let peer_report_config = PeerReportConfig {
            successful_block_import: 5.,

View on GitHub (pinned to b9d4d170da)

Solutions

  1. Set database_type to DbType::RocksDb (with a db path) in the combined db config when historical_execution is on.
  2. Or disable historical_execution if historical queries are not needed.
  3. In tests that need history, use RocksDB in a per-test temp directory.

Example fix

// before
let mut config = Config::local_node();
config.historical_execution = true;
config.combined_db_config.database_type = DbType::InMemory;

// after
config.historical_execution = true;
config.combined_db_config.database_type = DbType::RocksDb;
config.combined_db_config.path = Some(tempdir.path().into());
Defensive patterns

Strategy: validation

Validate before calling

use fuel_core::service::DbType;

fn assert_db_config_compatible(config: &fuel_core::service::Config) -> anyhow::Result<()> {
    if config.historical_execution
        && config.combined_db_config.database_type != DbType::RocksDb
    {
        return Err(anyhow::anyhow!(
            "historical_execution requires database_type = RocksDb"
        ));
    }
    Ok(())
}

// run before fuel_core::service::FuelService::new

Type guard

fn supports_historical_execution(db_type: fuel_core::service::DbType) -> bool {
    matches!(db_type, fuel_core::service::DbType::RocksDb)
}

Try / catch

match FuelService::new_node(config).await {
    Err(e) if e.to_string().contains("only supported with RocksDB") => {
        // flip database_type to RocksDb with a path, or disable historical_execution
    }
    rest => rest,
}

Prevention

When it happens

Trigger: Building or starting a FuelService with historical_execution: true while combined_db_config.database_type is DbType::InMemory.

Common situations: Test harnesses that default to in-memory databases copying production configs with historical queries enabled; refactors toggling historical_execution without adjusting the database config; CI configs diverging from production.

Related errors


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