{"record":{"id":"116326e82959e6a6","repo":"FuelLabs/fuel-core","slug":"could-not-convert-blob-witness-index-to-u16","errorCode":null,"errorMessage":"Could not convert blob witness_index to u16: {}","messagePattern":"Could not convert blob witness_index to u16: (.+?)","errorType":"exception","errorClass":"Error::Serialization","httpStatus":null,"severity":"error","filePath":"crates/services/block_aggregator_api/src/blocks/old_block_source/convertor_adapter/proto_to_fuel_conversions.rs","lineNumber":841,"sourceCode":"                .iter()\n                .map(input_from_proto_input)\n                .collect::<crate::result::Result<Vec<_>>>()?;\n            let outputs = proto_blob\n                .outputs\n                .iter()\n                .map(output_from_proto_output)\n                .collect::<crate::result::Result<Vec<_>>>()?;\n            let witnesses = proto_blob\n                .witnesses\n                .iter()\n                .map(|w| Ok(Witness::from(w.clone())))\n                .collect::<crate::result::Result<Vec<_>>>()?;\n            let blob_id = fuel_core_types::fuel_types::BlobId::try_from(\n                proto_blob.blob_id.as_slice(),\n            )\n            .map_err(|e| Error::Serialization(anyhow!(e)))?;\n            let witness_index = u16::try_from(proto_blob.witness_index).map_err(|e| {\n                Error::Serialization(anyhow!(\n                    \"Could not convert blob witness_index to u16: {}\",\n                    e\n                ))\n            })?;\n            let body = BlobBody {\n                id: blob_id,\n                witness_index,\n            };\n\n            let blob_tx =\n                FuelTransaction::blob(body, policies, inputs, outputs, witnesses);\n\n            Ok(FuelTransaction::Blob(blob_tx))\n        }\n    }\n}\n\nfn input_from_proto_input(proto_input: &ProtoInput) -> crate::result::Result<Input> {","sourceCodeStart":823,"sourceCodeEnd":859,"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#L823-L859","documentation":"Blob transactions reference their blob witness via BlobBody.witness_index, a u16 in fuel-core. The proto field is wider; u16::try_from fails for values above 65535 (or negative), raising this Error::Serialization while building the BlobBody.","triggerScenarios":"A Blob proto with witness_index > 65535 — typically a sentinel (u32::MAX / -1) meaning 'no witness', or a corrupted/mis-encoded payload. Valid transactions keep this well under the witness count.","commonSituations":"Cross-language encoders omitting range checks; sentinel values for optional witnesses; fuzzed data; version skew where a newer field semantics was back-filled into an old producer.","solutions":["Validate witness_index <= 65535 and < witnesses.len() before converting the Blob transaction","Fix the producer to emit a real witness index (blob transactions must attach the blob as a witness)","Map sentinel values explicitly during re-encoding rather than letting try_from fail","Add encode/decode round-trip tests for blob transactions in the producer's test suite"],"exampleFix":"// before\nlet witness_index = u16::try_from(proto_blob.witness_index).map_err(...)?;\n\n// after\nlet wi = proto_blob.witness_index;\nif wi > u16::MAX as u32 || wi as usize >= proto_blob.witnesses.len() {\n    return Err(anyhow!(\"blob witness_index {wi} invalid with {} witnesses\", proto_blob.witnesses.len()));\n}\nlet witness_index = wi as u16;","handlingStrategy":"validation","validationCode":"fn blob_witness_index_ok(b: &ProtoBlob) -> bool {\n    b.witness_index <= u16::MAX as u32 && (b.witness_index as usize) < b.witnesses.len()\n}","typeGuard":"fn fits_u16(v: u32) -> bool { v <= u16::MAX as u32 }","tryCatchPattern":"let witness_index = u16::try_from(b.witness_index)\n    .with_context(|| format!(\"blob witness_index {} with {} witnesses\", b.witness_index, b.witnesses.len()))?;","preventionTips":["Blob transactions must attach the blob witness; validate index < witnesses.len() pre-send","Never encode -1 or u32::MAX as witness_index","Re-verify blob tx protos with a decode pass before broadcasting"],"tags":["rust","fuel","protobuf","serialization","blob-transaction","integer-overflow","validation"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}