FuelLabs/fuel-core · error · anyhow::Error
On chain database is already initialized
Error message
On chain database is already initialized
What it means
execute_genesis_block converts the on-chain database into a fresh 'genesis' (empty) view via into_genesis(); that conversion fails if the database already contains a genesis/chain state. Genesis import is only valid on a truly empty on-chain DB — running it against initialized storage is refused.
Source
Thrown at crates/fuel-core/src/service/genesis.rs:83
mod exporter;
mod importer;
mod progress;
mod task_manager;
/// Performs the importing of the genesis block from the snapshot.
pub async fn execute_genesis_block(
watcher: StateWatcher,
config: &Config,
db: &CombinedDatabase,
) -> anyhow::Result<UncommittedImportResult<Changes>> {
let genesis_block = create_genesis_block(config);
tracing::info!("Genesis block created: {:?}", genesis_block.header());
let on_chain = db
.on_chain()
.clone()
.into_genesis()
.map_err(|_| anyhow::anyhow!("On chain database is already initialized"))?;
let off_chain = db
.off_chain()
.clone()
.into_genesis()
.map_err(|_| anyhow::anyhow!("Off chain database is already initialized"))?;
let genesis_db = CombinedGenesisDatabase {
on_chain,
off_chain,
};
SnapshotImporter::import(
genesis_db.clone(),
genesis_block.clone(),
config.snapshot_reader.clone(),
watcher,
)
.await?;View on GitHub (pinned to b9d4d170da)
Solutions
- If re-genesis is intended: stop the node and wipe the database (delete the db directory / use the node's wipe-db option).
- If the DB should be kept: don't run genesis import — the chain is already initialized; start from the existing state.
- Ensure only one of {fresh genesis, existing chain} is attempted per db-path.
Defensive patterns
Strategy: validation
Validate before calling
// Before executing genesis import, check whether the chain DB already has
// state (e.g. a genesis block / chain height record):
async fn needs_genesis(db: &CombinedDatabase) -> bool {
db.on_chain()
.latest_height() // or equivalent 'is empty' probe for your version
.is_err() // no state yet
}
if !needs_genesis(&db).await {
tracing::info!("chain already initialized; skipping genesis import");
} Try / catch
if let Err(e) = genesis_result {
if e.to_string().contains("already initialized") {
// decide explicitly: wipe and re-genesis, or continue from state
return Err(anyhow!("DB not empty: wipe db-path or skip genesis import"));
}
return Err(e);
} Prevention
- Use a fresh db-path per chain instance; never share data directories.
- Run genesis import only as part of first-initialization flows, guarded by an emptiness check.
- Automate wipe-db before re-genesis in test/CI harnesses.
When it happens
Trigger: Node startup (or an explicit genesis import) runs execute_genesis_block while the DB at the configured path already has state — e.g. restarting against the same db-path after a previous partial run.
Common situations: Reusing a data directory across node restarts with a workflow that always runs genesis import; CI reusing db paths; changing genesis config while keeping the old database.
Related errors
- Off chain database is already initialized
- on-chain database doesn't have height
- off-chain database doesn't have height
- Database doesn't have a height to rollback
- The genesis block height is not found in the database during
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/aa6db741990755d4.
Report an issue: GitHub.