{"record":{"id":"37affbe019e0221c","repo":"linera-io/linera-protocol","slug":"storage-error-while-reading-chain-description-e","errorCode":null,"errorMessage":"Storage error while reading chain description: {e}","messagePattern":"Storage error while reading chain description: (.+?)","errorType":"exception","errorClass":"async_graphql::Error","httpStatus":null,"severity":"error","filePath":"linera-faucet/server/src/lib.rs","lineNumber":698,"sourceCode":"    chain_id: ChainId,\n) -> Result<ChainDescription, Error>\nwhere\n    S: Storage,\n{\n    // Create blob ID from chain ID - the chain ID is the hash of the chain description blob\n    let blob_id = BlobId::new(chain_id.0, BlobType::ChainDescription);\n\n    // Read the blob directly from storage\n    let blob = storage\n        .read_blob(blob_id)\n        .await\n        .map_err(|e| {\n            tracing::error!(\n                \"Failed to read chain description blob for {}: {}\",\n                chain_id,\n                e\n            );\n            Error::new(format!(\n                \"Storage error while reading chain description: {e}\"\n            ))\n        })?\n        .ok_or_else(|| {\n            tracing::error!(\"Chain description blob not found for chain {}\", chain_id);\n            Error::new(format!(\"Chain description not found for chain {chain_id}\"))\n        })?;\n\n    // Deserialize the chain description from the blob bytes\n    let description = bcs::from_bytes::<ChainDescription>(blob.bytes()).map_err(|e| {\n        tracing::error!(\n            \"Failed to deserialize chain description for {}: {}\",\n            chain_id,\n            e\n        );\n        Error::new(format!(\n            \"Invalid chain description data for chain {chain_id}\"\n        ))","sourceCodeStart":680,"sourceCodeEnd":716,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-faucet/server/src/lib.rs#L680-L716","documentation":"When an owner re-claims (duplicate `claim`), the faucet serves the stored chain by reading the ChainDescription blob directly: `storage.read_blob(BlobId::new(chain_id.0, BlobType::ChainDescription))`. This error wraps a failure returned by the storage backend itself; the underlying error is appended as `{e}` and logged as `Failed to read chain description blob for <chain>: <err>`. It means the backend (DynamoDB, ScyllaDB, Redis, service storage, ...) errored — not that the blob is merely absent.","triggerScenarios":"A duplicate `claim(owner)` for an owner with an existing chain while the storage backend fails: connection refused, expired credentials, missing table/keyspace, timeouts, or I/O errors from the backend surfaced through `read_blob`.","commonSituations":"Faucet storage env vars (endpoint, credentials, region) wrong or stale after a redeploy; the database container being down or restarted; network partition between faucet and storage; local faucets pointed at a stopped Redis/ScyllaDB instance.","solutions":["Read the appended `{e}` cause and the matching faucet log line to identify the backend error","Verify the storage backend the faucet was started with is reachable and its credentials are valid","Restart the faucet if the backend was restarted, so connections are re-established","Compare the current storage configuration with the one used when the chains were recorded — a different keyspace/table also surfaces here"],"exampleFix":"// before - surface the error directly\nlet chain = client.claim(owner, None).await?;\n\n// after - retry transient backend failures with backoff\nlet chain = match client.claim(owner, None).await {\n    Ok(chain) => chain,\n    Err(e) if e.message.starts_with(\"Storage error while reading chain description\") => {\n        // inspect e.message suffix; retry only transient causes (timeouts, connection resets)\n        retry_with_backoff(|| client.claim(owner, None), 3).await?\n    }\n    Err(e) => return Err(e),\n};","handlingStrategy":"retry","validationCode":null,"typeGuard":"fn is_storage_read_error(msg: &str) -> bool { msg.starts_with(\"Storage error while reading chain description\") }","tryCatchPattern":"Catch the claim error; if the message starts with `Storage error while reading chain description`, inspect the appended cause. Retry transient causes (timeouts, connection resets) with exponential backoff and a small cap; treat auth/misconfiguration causes as permanent and alert the faucet operator.","preventionTips":["Validate faucet storage env vars (endpoint, credentials, region, table/keyspace) at deploy time","Health-check the storage backend before pointing clients at a re-deployed faucet","Alert on repeated `Failed to read chain description blob` log lines — they precede client-visible failures","Keep the faucet's storage configuration identical across restarts"],"tags":["storage","backend","io","faucet","duplicate-claim","linera"],"backgroundTag":"database-read-failed","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}