{"record":{"id":"d22f3ec2f705374b","repo":"FuelLabs/fuel-core","slug":"could-not-convert-log-data-digest-to-bytes32","errorCode":null,"errorMessage":"Could not convert log data digest to Bytes32: {}","messagePattern":"Could not convert log data digest to Bytes32: (.+?)","errorType":"exception","errorClass":"Error::Serialization","httpStatus":500,"severity":"error","filePath":"crates/services/block_aggregator_api/src/blocks/old_block_source/convertor_adapter/proto_to_fuel_conversions.rs","lineNumber":388,"sourceCode":"            )\n        }\n        ProtoReceiptVariant::Revert(revert) => {\n            let id = ContractId::try_from(revert.id.as_slice())\n                .map_err(|e| Error::Serialization(anyhow!(e)))?;\n            Ok(FuelReceipt::revert(id, revert.ra, revert.pc, revert.is))\n        }\n        ProtoReceiptVariant::Log(log) => {\n            let id = ContractId::try_from(log.id.as_slice())\n                .map_err(|e| Error::Serialization(anyhow!(e)))?;\n            Ok(FuelReceipt::log(\n                id, log.ra, log.rb, log.rc, log.rd, log.pc, log.is,\n            ))\n        }\n        ProtoReceiptVariant::LogData(log) => {\n            let id = ContractId::try_from(log.id.as_slice())\n                .map_err(|e| Error::Serialization(anyhow!(e)))?;\n            let digest = Bytes32::try_from(log.digest.as_slice()).map_err(|e| {\n                Error::Serialization(anyhow!(\n                    \"Could not convert log data digest to Bytes32: {}\",\n                    e\n                ))\n            })?;\n            Ok(FuelReceipt::log_data_with_len(\n                id,\n                log.ra,\n                log.rb,\n                log.ptr,\n                log.len,\n                digest,\n                log.pc,\n                log.is,\n                log.data.clone(),\n            ))\n        }\n        ProtoReceiptVariant::Transfer(transfer) => {\n            let id = ContractId::try_from(transfer.id.as_slice())","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/services/block_aggregator_api/src/blocks/old_block_source/convertor_adapter/proto_to_fuel_conversions.rs#L370-L406","documentation":"Thrown while decoding a LogData receipt: the digest bytes field must be exactly 32 bytes for fuel's Bytes32; a different length fails try_from and is wrapped as Error::Serialization, aborting the receipt and block conversion.","triggerScenarios":"fuel_block_from_protobuf on a block where a LogData receipt's digest has a length other than 32 - corruption, truncation, or an encoder that does not fix the digest size.","commonSituations":"Producer/consumer version mismatch; corrupted transfer; hand-built receipts in tests.","solutions":["Log the digest length of the failing LogData receipt.","Pre-validate len == 32 for all receipt digest fields before decoding.","Pin matching fuel-core versions on both ends.","Reject and re-fetch the block."],"exampleFix":"// before\nlet digest = Bytes32::try_from(log.digest.as_slice()).map_err(|e| {\n    Error::Serialization(anyhow!(\"Could not convert log data digest to Bytes32: {}\", e))\n})?;\n\n// after\nif log.digest.len() != 32 {\n    return Err(Error::Serialization(anyhow::anyhow!(\n        \"LogData digest length {} != 32\", log.digest.len()\n    )));\n}","handlingStrategy":"validation","validationCode":"fn log_data_digest_valid(log: &ProtoLogData) -> bool {\n    log.digest.len() == 32\n}","typeGuard":"fn is_bytes32(b: &[u8]) -> bool { b.len() == 32 }","tryCatchPattern":"match receipt_from_proto(r) {\n    Ok(receipt) => out.push(receipt),\n    Err(Error::Serialization(ctx)) if ctx.to_string().contains(\"log data digest\") => {\n        tracing::warn!(len = log.digest.len(), \"rejecting LogData with bad digest\");\n        return Err(Error::Serialization(ctx));\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Validate digest length on LogData receipts before decoding blocks.","Keep encoder/decoder versions aligned; checksum stored blobs.","Build test receipts through fuel-core constructors so digests are always 32 bytes."],"tags":["rust","fuel-core","protobuf","deserialization","bytes32","receipts"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}