{"record":{"id":"520a4bb744727877","repo":"FuelLabs/fuel-core","slug":"relayer-database-height-relayer-db-height-is-le","errorCode":null,"errorMessage":"relayer database height({relayer_db_height}) is less than target height({target_da_height})","messagePattern":"relayer database height\\((.+?)\\) is less than target height\\((.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fuel-core/src/combined_database.rs","lineNumber":620,"sourceCode":"        target_da_height: DaBlockHeight,\n        shutdown_listener: &mut S,\n    ) -> anyhow::Result<()>\n    where\n        S: ShutdownListener,\n    {\n        while !shutdown_listener.is_cancelled() {\n            let relayer_db_height = self.relayer().latest_height_from_metadata()?;\n            let relayer_db_rolled_back =\n                is_equal_or_none(relayer_db_height, target_da_height);\n\n            if relayer_db_rolled_back {\n                break;\n            }\n\n            if let Some(relayer_db_height) = relayer_db_height\n                && relayer_db_height < target_da_height\n            {\n                return Err(anyhow::anyhow!(\n                    \"relayer database height({relayer_db_height}) \\\n                    is less than target height({target_da_height})\"\n                ));\n            }\n\n            if let Some(relayer_db_height) = relayer_db_height\n                && relayer_db_height > target_da_height\n            {\n                self.relayer().rollback_last_block()?;\n            }\n        }\n\n        if shutdown_listener.is_cancelled() {\n            return Err(anyhow::anyhow!(\n                \"Stop the rollback due to shutdown signal received\"\n            ));\n        }\n","sourceCodeStart":602,"sourceCodeEnd":638,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/fuel-core/src/combined_database.rs#L602-L638","documentation":"rollback_relayer_to rewinds the relayer (DA) database to a target DA block height. Its height is Optional, but if Some(height) is strictly below target_da_height the rollback aborts: the relayer DB would need to move forward, which rollback never does. The relayer DB must first catch up to (or past) the target before it can be trimmed back.","triggerScenarios":"Calling rollback_relayer_to with a DA height above the relayer database's recorded height — relayer lagging behind DA layer, or a target computed from chain/consensus metadata that the relayer DB has not reached.","commonSituations":"Relayer temporarily disabled or falling behind the DA layer; restoring the relayer DB from an old snapshot; passing an on-chain-derived DA height without validating relayer progress.","solutions":["Let the relayer sync forward from the DA layer until its height >= target_da_height, then retry the rollback.","Derive target_da_height from the relayer DB's own current height rather than from chain state.","If relayer history is disposable, wipe the relayer DB and let it re-sync."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if let Some(relayer_height) = db.relayer().latest_height_from_metadata()? {\n    if target_da_height > relayer_height {\n        anyhow::bail!(\"relayer at {} is behind target {}; sync the relayer first\", relayer_height, target_da_height);\n    }\n}\ndb.rollback_relayer_to(target_da_height, &mut shutdown)?;","typeGuard":null,"tryCatchPattern":"match db.rollback_relayer_to(target_da_height, &mut shutdown) {\n    Ok(()) => Ok(()),\n    Err(e) if e.to_string().contains(\"relayer database height\") => {\n        // relayer must move forward first: this is a sync problem, not a rollback problem\n        anyhow::bail!(\"sync relayer to >= {} before rollback: {}\", target_da_height, e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Compute the DA rollback target from the relayer DB's own height, not from chain state.","Keep the relayer running and healthy so its DB tracks the DA layer.","A relayer DB behind its target can be wiped and re-synced if history is disposable."],"tags":["database","relayer","rollback","da-height","rust"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}