linera-io/linera-protocol · error
Failed to clone storage
Error message
Failed to clone storage
What it means
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.
Source
Thrown at linera-exporter/src/runloops/task_manager.rs:138
}
}
pub(super) async fn join_all(self) {
for (id, handle) in self.join_handles {
// Wait for all tasks to finish.
if let Err(e) = handle.await.unwrap() {
tracing::error!(id=?id, error=?e, "failed to join task");
}
}
}
fn spawn(&mut self, id: DestinationId) {
if self.join_handles.contains_key(&id) {
tracing::trace!(id=?id, "exporter already running, skipping spawn");
return;
}
let exporter_builder = &self.exporters_builder;
let storage = self.storage.clone().expect("Failed to clone storage");
let join_handle = exporter_builder.spawn(id.clone(), storage);
self.join_handles.insert(id, join_handle);
}
}
/// All the data required by a thread to spawn different tasks
/// on its runtime, join the thread, handle the committees etc.
pub(super) struct ExporterBuilder<F> {
options: NodeOptions,
work_queue_size: usize,
node_provider: Arc<GrpcNodeProvider>,
shutdown_signal: F,
health: Arc<AtomicBool>,
}
impl<F> ExporterBuilder<F>
where
F: IntoFuture<Output = ()> + Clone + Send + Sync + 'static,View on GitHub (pinned to 6c226ddcb3)
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.
Defensive patterns
Strategy: validation
Validate before calling
// Validate storage connectivity before launching the exporter runloop:
// (example for a Postgres-backed storage)
let conn = tokio_postgres::connect(&config.storage.connection_string, tokio_postgres::NoTls).await;
if conn.is_err() {
anyhow::bail!("storage backend unreachable; fix the connection string before starting exporters");
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unable to read the configuration file
- Failed to create log file
- owner should be different from spender
- invalid block export configuration: {message}
- Returned AccountInfo should have code: Some(...) and so code
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/ecd0e57bdd4e35b4.
Report an issue: GitHub.