{"record":{"id":"aa6db741990755d4","repo":"FuelLabs/fuel-core","slug":"on-chain-database-is-already-initialized","errorCode":null,"errorMessage":"On chain database is already initialized","messagePattern":"On chain database is already initialized","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/fuel-core/src/service/genesis.rs","lineNumber":83,"sourceCode":"\nmod exporter;\nmod importer;\nmod progress;\nmod task_manager;\n\n/// Performs the importing of the genesis block from the snapshot.\npub async fn execute_genesis_block(\n    watcher: StateWatcher,\n    config: &Config,\n    db: &CombinedDatabase,\n) -> anyhow::Result<UncommittedImportResult<Changes>> {\n    let genesis_block = create_genesis_block(config);\n    tracing::info!(\"Genesis block created: {:?}\", genesis_block.header());\n    let on_chain = db\n        .on_chain()\n        .clone()\n        .into_genesis()\n        .map_err(|_| anyhow::anyhow!(\"On chain database is already initialized\"))?;\n    let off_chain = db\n        .off_chain()\n        .clone()\n        .into_genesis()\n        .map_err(|_| anyhow::anyhow!(\"Off chain database is already initialized\"))?;\n\n    let genesis_db = CombinedGenesisDatabase {\n        on_chain,\n        off_chain,\n    };\n\n    SnapshotImporter::import(\n        genesis_db.clone(),\n        genesis_block.clone(),\n        config.snapshot_reader.clone(),\n        watcher,\n    )\n    .await?;","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/fuel-core/src/service/genesis.rs#L65-L101","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before executing genesis import, check whether the chain DB already has\n// state (e.g. a genesis block / chain height record):\nasync fn needs_genesis(db: &CombinedDatabase) -> bool {\n    db.on_chain()\n        .latest_height() // or equivalent 'is empty' probe for your version\n        .is_err() // no state yet\n}\nif !needs_genesis(&db).await {\n    tracing::info!(\"chain already initialized; skipping genesis import\");\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = genesis_result {\n    if e.to_string().contains(\"already initialized\") {\n        // decide explicitly: wipe and re-genesis, or continue from state\n        return Err(anyhow!(\"DB not empty: wipe db-path or skip genesis import\"));\n    }\n    return Err(e);\n}","preventionTips":["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."],"tags":["genesis","database","initialization"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}