{"record":{"id":"ecd0e57bdd4e35b4","repo":"linera-io/linera-protocol","slug":"failed-to-clone-storage","errorCode":null,"errorMessage":"Failed to clone storage","messagePattern":"Failed to clone storage","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-exporter/src/runloops/task_manager.rs","lineNumber":138,"sourceCode":"        }\n    }\n\n    pub(super) async fn join_all(self) {\n        for (id, handle) in self.join_handles {\n            // Wait for all tasks to finish.\n            if let Err(e) = handle.await.unwrap() {\n                tracing::error!(id=?id, error=?e, \"failed to join task\");\n            }\n        }\n    }\n\n    fn spawn(&mut self, id: DestinationId) {\n        if self.join_handles.contains_key(&id) {\n            tracing::trace!(id=?id, \"exporter already running, skipping spawn\");\n            return;\n        }\n        let exporter_builder = &self.exporters_builder;\n        let storage = self.storage.clone().expect(\"Failed to clone storage\");\n        let join_handle = exporter_builder.spawn(id.clone(), storage);\n        self.join_handles.insert(id, join_handle);\n    }\n}\n\n/// All the data required by a thread to spawn different tasks\n/// on its runtime, join the thread, handle the committees etc.\npub(super) struct ExporterBuilder<F> {\n    options: NodeOptions,\n    work_queue_size: usize,\n    node_provider: Arc<GrpcNodeProvider>,\n    shutdown_signal: F,\n    health: Arc<AtomicBool>,\n}\n\nimpl<F> ExporterBuilder<F>\nwhere\n    F: IntoFuture<Output = ()> + Clone + Send + Sync + 'static,","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-exporter/src/runloops/task_manager.rs#L120-L156","documentation":"ExportersTracker::spawn (linera-exporter/src/runloops/task_manager.rs:132) clones the shared exporter storage before spawning a per-destination exporter and expects success. ExporterStorage::clone (linera-exporter/src/storage.rs:211) is a fallible custom clone: it re-clones the underlying linera storage backend, which can return Err (e.g. storage client/pool construction failing against a misconfigured or unreachable database). The panic aborts the runloop thread that manages exporters.","triggerScenarios":"A committee change or startup causing spawn() for a new DestinationId while the underlying storage backend's clone fails - typically a bad connection string or a database (Postgres/DynamoDB/ScyllaDB) that is unreachable or rejecting connections at clone time.","commonSituations":"Exporter config's storage connection string wrong or pointing at a down database; DB credentials rotated after exporter start; network partition to the storage endpoint while committees rotate, triggering a spawn attempt.","solutions":["Verify the storage backend is reachable with the connection settings in the exporter config (e.g. psql for Postgres endpoints).","Correct the storage connection string / credentials in the config and restart the exporter.","Check exporter logs just before the panic for the underlying storage error naming the real cause.","If the DB restarts, restart the exporter so storage clones succeed on the next spawn."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate storage connectivity before launching the exporter runloop:\n// (example for a Postgres-backed storage)\nlet conn = tokio_postgres::connect(&config.storage.connection_string, tokio_postgres::NoTls).await;\nif conn.is_err() {\n    anyhow::bail!(\"storage backend unreachable; fix the connection string before starting exporters\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Health-check the database endpoint (network probe or simple query) before starting the exporter.","Keep DB credentials in a managed secret and rotate them together with exporter restarts.","Monitor exporter logs for storage errors - spawn panics during committee changes are preceded by storage failures."],"tags":["linera-exporter","storage","database-connection","panic","rust"],"backgroundTag":"database-connection-failure","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}