linera-io/linera-protocol · error · async_graphql::Error

Chain description not found for chain {chain_id}

Error message

Chain description not found for chain {chain_id}

What it means

On a duplicate `claim`, `read_blob` succeeded but returned `None`: the faucet's database maps the owner to a chain_id whose ChainDescription blob is no longer present in blob storage. A ChainId is the hash of its description blob, so the blob should always exist once the chain is registered — its absence means the faucet's claim database and its blob storage are out of sync (one was wiped or replaced while the other survived).

Source

Thrown at linera-faucet/server/src/lib.rs:704

    let blob_id = BlobId::new(chain_id.0, BlobType::ChainDescription);

    // Read the blob directly from storage
    let blob = storage
        .read_blob(blob_id)
        .await
        .map_err(|e| {
            tracing::error!(
                "Failed to read chain description blob for {}: {}",
                chain_id,
                e
            );
            Error::new(format!(
                "Storage error while reading chain description: {e}"
            ))
        })?
        .ok_or_else(|| {
            tracing::error!("Chain description blob not found for chain {}", chain_id);
            Error::new(format!("Chain description not found for chain {chain_id}"))
        })?;

    // Deserialize the chain description from the blob bytes
    let description = bcs::from_bytes::<ChainDescription>(blob.bytes()).map_err(|e| {
        tracing::error!(
            "Failed to deserialize chain description for {}: {}",
            chain_id,
            e
        );
        Error::new(format!(
            "Invalid chain description data for chain {chain_id}"
        ))
    })?;

    Ok(description)
}

impl<C> BatchProcessor<C>

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Restore or re-sync the blob store that contained the chain description blobs so it is consistent with the faucet's claim database
  2. Otherwise reset the faucet's claim database to clear stale owner-to-chain mappings, letting owners re-claim
  3. Ensure the faucet is configured with the same storage backend and endpoint used when the chains were created
  4. If neither is possible, take the faucet out of rotation and escalate to the operator — the mapping data is inconsistent
Defensive patterns

Strategy: try-catch

Type guard

fn is_chain_description_missing(msg: &str) -> bool { msg.starts_with("Chain description not found for chain") }

Try / catch

Catch the claim error; on `Chain description not found for chain <id>`, do not retry — the faucet's owner-to-chain mapping references a blob that is gone. Report the chain ID to the faucet operator; the fix is on the server side (re-sync blob storage or reset the faucet's claim records).

Prevention

When it happens

Trigger: Blob storage deleted/pruned/recreated while the faucet's claim database survived (exactly the scenario test_blockchain_sync_after_database_deletion exercises); the faucet repointed to a different or empty storage backend after chains were recorded; GC pruning blobs on shared storage.

Common situations: Deleting the database directory (or `linera net down && up`) under a persistent faucet; switching storage backends between runs (e.g. memory to DynamoDB) without clearing faucet records; partial restores from backup that include the mapping tables but not the blobs.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/5ecd0dd9235f9902. Report an issue: GitHub.