{"record":{"id":"7a4753de37425bb5","repo":"FuelLabs/fuel-core","slug":"on-chain-database-height-on-chain-height-is-les","errorCode":null,"errorMessage":"on-chain database height({on_chain_height}) is less than target height({target_block_height})","messagePattern":"on-chain database height\\((.+?)\\) is less than target height\\((.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fuel-core/src/combined_database.rs","lineNumber":524,"sourceCode":"                    && block_aggregation_storage_rolled_back\n                {\n                    break;\n                }\n            }\n\n            #[cfg(not(feature = \"rpc\"))]\n            {\n                if on_chain_height == target_block_height\n                    && off_chain_height == target_block_height\n                    && gas_price_rolled_back\n                    && compression_db_rolled_back\n                {\n                    break;\n                }\n            }\n\n            if on_chain_height < target_block_height {\n                return Err(anyhow::anyhow!(\n                    \"on-chain database height({on_chain_height}) \\\n                    is less than target height({target_block_height})\"\n                ));\n            }\n\n            if off_chain_height < target_block_height {\n                return Err(anyhow::anyhow!(\n                    \"off-chain database height({off_chain_height}) \\\n                    is less than target height({target_block_height})\"\n                ));\n            }\n\n            if let Some(gas_price_chain_height) = gas_price_chain_height\n                && gas_price_chain_height < target_block_height\n            {\n                return Err(anyhow::anyhow!(\n                    \"gas-price database height({gas_price_chain_height}) \\\n                    is less than target height({target_block_height})\"","sourceCodeStart":506,"sourceCodeEnd":542,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/fuel-core/src/combined_database.rs#L506-L542","documentation":"During rollback_to, after reading current heights, the function refuses to 'roll back' to a target that is above the on-chain database's current height — rollback only moves backward, so a target in the future means the database never reached that height and the request is inconsistent. This guard prevents silently treating a lagging database as rolled back.","triggerScenarios":"Calling rollback_to with target_block_height greater than the on-chain database's latest committed height — e.g., a wrong target height argument, or database divergence where the on-chain DB is behind what the caller assumed.","commonSituations":"Misconfigured rollback/re-org target (off-by-one or wrong chain); restoring an on-chain DB from an older snapshot while passing a newer target; mixed-height databases after a crash where components are at inconsistent heights.","solutions":["Query the current on-chain height first and pass a target_block_height <= it.","If the on-chain DB is legitimately behind, re-sync it (from peers or snapshot) until it reaches the target, then roll back.","Restore all component databases from one consistent snapshot so heights agree."],"exampleFix":"// before\ncombined_db.rollback_to(target_block_height, &mut shutdown)?;\n\n// after\nlet current = combined_db.on_chain().latest_height_from_metadata()?.expect(\"height\");\nlet target = target_block_height.min(current); // never roll 'forward'\ncombined_db.rollback_to(target, &mut shutdown)?;","handlingStrategy":"validation","validationCode":"let on_chain = combined_db\n    .on_chain()\n    .latest_height_from_metadata()?\n    .ok_or_else(|| anyhow::anyhow!(\"on-chain DB empty\"))?;\nif target_block_height > on_chain {\n    anyhow::bail!(\"target {} above on-chain height {}; sync first\", target_block_height, on_chain);\n}\ncombined_db.rollback_to(target_block_height, &mut shutdown)?;","typeGuard":null,"tryCatchPattern":"match combined_db.rollback_to(target, &mut shutdown) {\n    Ok(()) => Ok(()),\n    Err(e) if e.to_string().contains(\"is less than target height\") => {\n        // database behind target: sync forward, do not retry the same rollback\n        anyhow::bail!(\"database behind target; re-sync to at least {} then retry\", target)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Compute rollback targets from the database's own current height, never from external chain state.","Clamp targets with target.min(current_height).","Keep component databases at consistent heights by restoring from one snapshot."],"tags":["database","rollback","height-mismatch","rust"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}