{"record":{"id":"6f968f5d247260ae","repo":"FuelLabs/fuel-core","slug":"the-override-height-is-zero-the-override-height-s","errorCode":null,"errorMessage":"The override height is zero. The override height should be greater than zero.","messagePattern":"The override height is zero\\. The override height should be greater than zero\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fuel-core/src/service.rs","lineNumber":335,"sourceCode":"                            start_up_consensus_config,\n                            &header,\n                            &poa_seal,\n                        );\n\n                        if !block_valid {\n                            found_override_height = Some(override_height);\n                        }\n                    } else {\n                        return Err(anyhow::anyhow!(\n                            \"The consensus at override height {override_height} is not PoA.\"\n                        ));\n                    };\n                }\n            }\n        }\n\n        if let Some(override_height) = found_override_height {\n            let rollback_height = override_height.pred().ok_or(anyhow::anyhow!(\n                \"The override height is zero. \\\n                The override height should be greater than zero.\"\n            ))?;\n            tracing::warn!(\n                \"The consensus at override height {override_height} \\\n                does not match with the database. \\\n                Rollbacking the database to the height {rollback_height}\"\n            );\n            combined_database.rollback_to(rollback_height, shutdown_listener)?;\n        }\n\n        Ok(())\n    }\n\n    fn override_chain_config_if_needed(&self) -> anyhow::Result<()> {\n        let chain_config = self.shared.config.snapshot_reader.chain_config();\n        let on_chain_view = self.shared.database.on_chain().latest_view()?;\n        let chain_config_hash = chain_config.root()?.into();","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/fuel-core/src/service.rs#L317-L353","documentation":"Thrown at node startup by make_database_compatible_with_config (crates/fuel-core/src/service.rs:335). For ConsensusConfig::PoAV2 the node iterates poa.get_all_overrides(); when the stored block's PoA seal at an override height fails verify_consensus against the startup config, it plans a rollback to override_height - 1 via BlockHeight::pred(). An override at height 0 makes pred() return None, and since there is no height before genesis to roll back to, startup aborts with this error.","triggerScenarios":"A PoAV2 chain config whose overrides map contains key height 0 (or BlockHeight::default()), used against a non-empty on-chain database whose genesis-block PoA seal no longer verifies under the new consensus config (e.g., changed/re-ordered signing keys).","commonSituations":"Editing PoAV2 signing-key overrides to take effect 'from genesis' while reusing an existing database; writing the first override height as 0 in a custom chain config; rotating compromised consensus keys without re-initializing the DB.","solutions":["Move the PoAV2 override to a height greater than 0 (e.g., 1) so rollback to height-1 exists","Wipe/regenerate the on-chain database so genesis is re-executed under the new consensus instead of rolled back","If the goal was only new genesis keys, re-execute genesis with the new chain config rather than declaring an override at height 0","Add a config lint that rejects override keys equal to 0 before startup"],"exampleFix":"// before (chain config consensus.PoAV2):\n//   overrides: { \"0\": { \"signing_keys\": [new_keys] } }\n// after:\n//   overrides: { \"1\": { \"signing_keys\": [new_keys] } }\n//   (or start with a fresh database so the new keys apply at genesis)","handlingStrategy":"validation","validationCode":"fn overrides_rollbackable(poa: &PoAConfig) -> anyhow::Result<()> {\n    for h in poa.get_all_overrides().keys() {\n        anyhow::ensure!(!h.is_zero(),\n            \"override at height 0 cannot be rolled back; use height >= 1\");\n    }\n    Ok(())\n}\n// run before node start, before make_database_compatible_with_config","typeGuard":null,"tryCatchPattern":"match NodeProvider::start(&config).await {\n    Err(e) if e.to_string().contains(\"The override height is zero\") => {\n        // config/DB mismatch at genesis: fix overrides or wipe DB, do not retry\n        eprintln!(\"override at height 0 is unsupported; move it above 0 or re-init the DB\");\n        return Err(e);\n    }\n    other => other,\n}","preventionTips":["Never place a PoAV2 override at height 0; the first overridable height is 1","Treat 'change genesis consensus on an existing DB' as a re-genesis operation: wipe or migrate the database deliberately","Lint chain configs in CI: reject override keys < 1"],"tags":["fuel-core","poa","consensus","database","chain-config","startup"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}