{"record":{"id":"5f26db7d10ca4453","repo":"linera-io/linera-protocol","slug":"node-returned-a-blobsnotfound-error-with-an-empty","errorCode":null,"errorMessage":"Node returned a BlobsNotFound error with an empty list of missing blob IDs","messagePattern":"Node returned a BlobsNotFound error with an empty list of missing blob IDs","errorType":"validation","errorClass":"NodeError","httpStatus":null,"severity":"error","filePath":"linera-core/src/remote_node.rs","lineNumber":292,"sourceCode":"\n        ensure!(\n            expected_heights.is_empty(),\n            NodeError::MissingCertificatesByHeights {\n                chain_id,\n                heights: expected_heights.into_iter().collect(),\n            }\n        );\n        Ok(certificates)\n    }\n\n    /// Checks that requesting these blobs when trying to handle this certificate is legitimate,\n    /// i.e. that there are no duplicates and the blobs are actually required.\n    pub fn check_blobs_not_found<C: Certified>(\n        &self,\n        certificate: &C,\n        blob_ids: &[BlobId],\n    ) -> Result<(), NodeError> {\n        ensure!(!blob_ids.is_empty(), NodeError::EmptyBlobsNotFound);\n        let required = certificate.value().required_blob_ids();\n        for blob_id in blob_ids {\n            if !required.contains(blob_id) {\n                info!(\n                    address = self.address(),\n                    %blob_id,\n                    \"validator requested blob but it is not required\",\n                );\n                return Err(NodeError::UnexpectedEntriesInBlobsNotFound);\n            }\n        }\n        let unique_missing_blob_ids = blob_ids.iter().copied().collect::<HashSet<_>>();\n        if blob_ids.len() > unique_missing_blob_ids.len() {\n            info!(\n                address = self.address(),\n                \"blobs requested by validator contain duplicates\",\n            );\n            return Err(NodeError::DuplicatesInBlobsNotFound);","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-core/src/remote_node.rs#L274-L310","documentation":"Raised by RemoteNode::check_blobs_not_found, used from send_confirmed_certificate and send_validated_certificate when a validator rejects a certificate with BlobsNotFound. The client validates the complaint: the missing-blob list must be non-empty. An empty BlobsNotFound violates the protocol (the validator must name the blobs it lacks), so the client rejects the response instead of looping forever trying to satisfy an unnamed requirement.","triggerScenarios":"A buggy or malicious validator returns a BlobsNotFound error carrying an empty Vec<BlobId>; version drift where an older validator emits the error shape without the payload. Duplicates or blobs not actually required by the certificate are reported separately (DuplicatesInBlobsNotFound / UnexpectedEntriesInBlobsNotFound).","commonSituations":"Mixed validator versions during an upgrade where the error payload changed; adversarial validators trying to stall certificate delivery; regressions in validator proxy serialization dropping the inner vector.","solutions":["Skip the offending validator and continue with the rest of the committee (blob delivery only needs working validators)","Check validator versions — upgrade the one emitting malformed BlobsNotFound","If behind a proxy, inspect whether it serializes the error payload losslessly","Report the validator; an empty missing-list is a protocol violation"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":"fn is_empty_blobs_not_found(err: &NodeError) -> bool {\n    matches!(err, NodeError::EmptyBlobsNotFound)\n}","tryCatchPattern":"match send_certificate_to_validator(cert, &node).await {\n    Err(NodeError::EmptyBlobsNotFound) => {\n        // Malformed complaint: skip this validator, the remaining quorum suffices.\n        Ok(())\n    }\n    other => other,\n}","preventionTips":["Pin validator versions to a release compatible with the client's blob-error format","Monitor for validators emitting empty or malformed BlobsNotFound and remove them from rotation","Run certificate delivery against multiple validators so one bad responder never blocks progress"],"tags":["linera","validators","blobs","response-validation","protocol-error"],"backgroundTag":"invalid-validator-response","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}