{"record":{"id":"738c09463e26159e","repo":"FuelLabs/fuel-core","slug":"stop-the-rollback-due-to-shutdown-signal-received","errorCode":null,"errorMessage":"Stop the rollback due to shutdown signal received","messagePattern":"Stop the rollback due to shutdown signal received","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/fuel-core/src/combined_database.rs","lineNumber":591,"sourceCode":"            }\n\n            #[cfg(feature = \"rpc\")]\n            {\n                let block_aggregation_storage_height = self\n                    .block_aggregation_storage()\n                    .latest_height_from_metadata()?;\n\n                if let Some(block_aggregation_storage_height) =\n                    block_aggregation_storage_height\n                    && block_aggregation_storage_height > target_block_height\n                {\n                    self.block_aggregation_storage().rollback_last_block()?;\n                }\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\n        Ok(())\n    }\n\n    /// Rollbacks the state of the relayer to a specific block height.\n    pub fn rollback_relayer_to<S>(\n        &self,\n        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()?;","sourceCodeStart":573,"sourceCodeEnd":609,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/fuel-core/src/combined_database.rs#L573-L609","documentation":"rollback_to runs in a loop that checks a ShutdownListener each iteration so a shutting-down node stops promptly. If the listener reports cancellation before all databases reached the target height, the function returns this error instead of Ok — a partially completed rollback must not be reported as success. This is an expected, cooperative-shutdown error, not corruption; progress made so far is retained and the rollback resumes on the next attempt.","triggerScenarios":"Node receives Ctrl-C / SIGTERM / service-manager stop while a rollback_to is in progress and not yet finished.","commonSituations":"Long rollbacks (large height gaps) interrupted by restarts, deployments, or orchestrator-driven shutdowns; CI environments killing nodes under test.","solutions":["Restart the node and re-run the rollback — it is resumable; already-rolled-back heights are skipped.","Avoid sending shutdown signals until rollback completes, or schedule rollbacks during maintenance windows.","Monitor the rollback progress and only stop once it reports success."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Nothing to validate ahead of time: the shutdown signal is external.\n// Optional: check listener state before starting.\nif shutdown_listener.is_cancelled() {\n    anyhow::bail!(\"refusing to start rollback: shutdown already requested\");\n}\ncombined_db.rollback_to(target, &mut shutdown)?;","typeGuard":null,"tryCatchPattern":"loop {\n    match combined_db.rollback_to(target, &mut shutdown) {\n        Ok(()) => break,\n        Err(e) if e.to_string().contains(\"shutdown signal received\") => {\n            // partial rollback retained; resume after restart / when not cancelling\n            if shutdown_listener.is_cancelled() { return Err(e); }\n            continue;\n        }\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["Run long rollbacks in maintenance windows with shutdown signals deferred.","Treat this error as 'incomplete, resumable' — never as corruption.","Log rollback progress so operators can see how much remains before stopping a node."],"tags":["database","rollback","shutdown","graceful-degradation","rust"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}