{"record":{"id":"79f0174e7f48d2d9","repo":"linera-io/linera-protocol","slug":"blobsnotfound","errorCode":"BlobsNotFound","errorMessage":"Blobs not found: {0:?}","messagePattern":"Blobs not found: (.+?)","errorType":"validation","errorClass":"WorkerError","httpStatus":null,"severity":"error","filePath":"linera-core/src/chain_worker/state.rs","lineNumber":462,"sourceCode":"            .await?\n            .ok_or(WorkerError::BlobsNotFound(vec![blob_id]))\n    }\n\n    /// Reads the blobs from the chain manager or from storage. Returns an error if any are\n    /// missing.\n    #[instrument(skip_all, fields(\n        chain_id = %self.chain_id()\n    ))]\n    async fn get_required_blobs(\n        &self,\n        required_blob_ids: impl IntoIterator<Item = BlobId>,\n        created_blobs: BTreeMap<BlobId, Blob>,\n    ) -> Result<BTreeMap<BlobId, Blob>, WorkerError> {\n        let maybe_blobs = self\n            .maybe_get_required_blobs(required_blob_ids, Some(created_blobs))\n            .await?;\n        let not_found_blob_ids = missing_blob_ids(&maybe_blobs);\n        ensure!(\n            not_found_blob_ids.is_empty(),\n            WorkerError::BlobsNotFound(not_found_blob_ids)\n        );\n        Ok(maybe_blobs\n            .into_iter()\n            .filter_map(|(blob_id, maybe_blob)| Some((blob_id, maybe_blob?)))\n            .collect())\n    }\n\n    /// Tries to read the blobs from the chain manager or storage. Returns `None` if not found.\n    #[instrument(skip_all, fields(\n        chain_id = %self.chain_id()\n    ))]\n    async fn maybe_get_required_blobs(\n        &self,\n        blob_ids: impl IntoIterator<Item = BlobId>,\n        mut created_blobs: Option<BTreeMap<BlobId, Blob>>,\n    ) -> Result<BTreeMap<BlobId, Option<Blob>>, WorkerError> {","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-core/src/chain_worker/state.rs#L444-L480","documentation":"A block references blobs by ID (contract bytecode, committee blobs, data blobs it reads or publishes). get_required_blobs looks in the block's own created blobs, the manager's pending blobs, and storage; any ID found nowhere is returned in this error, aborting proposal or certificate processing.","triggerScenarios":"try_handle_block_proposal or process_confirmed_block for a block whose required_blob_ids are unknown to this validator. For proposals, load_proposal_blobs first registers the missing IDs as pending blobs and expects the client to upload each blob and retry.","commonSituations":"Publishing a block that reads or publishes blobs without uploading blob content to the validators first; a validator that never received the blob via gossip; blob pruning/GC removing a still-referenced blob; new node syncing without blob backfill.","solutions":["Upload the missing blobs (the error lists the exact BlobIds) via the blob endpoint / publish_blob, then retry the proposal or certificate","When proposing, publish blob content before or together with the block so validators can fetch or receive it","Ensure blob propagation/gossip is configured so validators request missing blobs from peers instead of failing"],"exampleFix":"// before: block references blobs the validator does not have\nclient.submit_proposal(proposal).await?; // BlobsNotFound([...])\n\n// after: upload each listed blob, then retry the same proposal\nfor blob_id in missing_blob_ids {\n    let blob = local_blob_store.read(blob_id)?; // or fetch from another node\n    client.publish_blob(chain_id, blob).await?;\n}\nclient.submit_proposal(proposal).await?;","handlingStrategy":"retry","validationCode":"// Pre-upload blobs the block depends on, so the proposal is never rejected.\nfor blob_id in block.required_blob_ids() {\n    if client.read_blob(blob_id).await?.is_none() {\n        let blob = local_store.read(blob_id)?; // or fetch from a peer\n        client.publish_blob(chain_id, blob).await?;\n    }\n}\nclient.submit_proposal(proposal).await?;","typeGuard":"fn blobs_not_found(e: &WorkerError) -> Option<&Vec<BlobId>> {\n    match e {\n        WorkerError::BlobsNotFound(ids) => Some(ids),\n        _ => None,\n    }\n}","tryCatchPattern":"match client.submit_proposal(proposal).await {\n    Err(e) if matches!(e, ref x if x.blobs_not_found().is_some()) => {\n        for blob_id in e.blobs_not_found().unwrap() {\n            let blob = local_store.read(blob_id)?; // or fetch from peers\n            client.publish_blob(chain_id, blob).await?;\n        }\n        client.submit_proposal(proposal).await?; // retry unchanged\n    }\n    other => other?,\n}","preventionTips":["Publish blob content to validators before or together with blocks that reference it","Keep blob propagation (gossip) enabled so validators backfill missing blobs automatically","Configure blob retention/GC so still-referenced blobs are never pruned"],"tags":["blobs","storage","block-proposal","missing-data","linera"],"backgroundTag":"missing-blob","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}