FuelLabs/fuel-core · error · Error::Serialization
Could not convert storage slot value to Bytes32: {}
Error message
Could not convert storage slot value to Bytes32: {} What it means
Thrown by storage_slot_from_proto when the proto storage slot's value field cannot be converted: Bytes32::try_from only accepts exactly 32 bytes, and proto.value has a different length. It is wrapped as Error::Serialization and fails the slot, the containing Create transaction, and the block decode.
Source
Thrown at crates/services/block_aggregator_api/src/blocks/old_block_source/convertor_adapter/proto_to_fuel_conversions.rs:98
let block_height = proto.block_height.into();
#[allow(clippy::useless_conversion)]
let tx_index = proto.tx_index.try_into().map_err(|e| {
Error::Serialization(anyhow!("Could not convert tx_index to target type: {}", e))
})?;
Ok(TxPointer::new(block_height, tx_index))
}
fn storage_slot_from_proto(
proto: &ProtoStorageSlot,
) -> crate::result::Result<StorageSlot> {
let key = Bytes32::try_from(proto.key.as_slice()).map_err(|e| {
Error::Serialization(anyhow!(
"Could not convert storage slot key to Bytes32: {}",
e
))
})?;
let value = Bytes32::try_from(proto.value.as_slice()).map_err(|e| {
Error::Serialization(anyhow!(
"Could not convert storage slot value to Bytes32: {}",
e
))
})?;
Ok(StorageSlot::new(key, value))
}
fn contract_input_from_proto(
proto: &ProtoContractInput,
) -> crate::result::Result<fuel_core_types::fuel_tx::input::contract::Contract> {
let utxo_proto = proto.utxo_id.as_ref().ok_or_else(|| {
Error::Serialization(anyhow!("Missing utxo_id on contract input"))
})?;
let utxo_id = utxo_id_from_proto(utxo_proto)?;
let balance_root = Bytes32::try_from(proto.balance_root.as_slice()).map_err(|e| {
Error::Serialization(anyhow!("Could not convert balance_root to Bytes32: {}", e))
})?;
let state_root = Bytes32::try_from(proto.state_root.as_slice()).map_err(|e| {View on GitHub (pinned to b9d4d170da)
Solutions
- Log the actual value length of the failing slot to confirm the mismatch.
- Validate slot.key and slot.value are both 32 bytes before decoding; reject the block early with slot position in the error.
- Align producer and consumer fuel-core versions so storage slot values are always 32 bytes.
- Re-fetch the block from a healthy peer or re-encode from canonical on-chain data.
Example fix
// before
let slot = storage_slot_from_proto(proto_slot)?;
// after
if proto_slot.value.len() != 32 {
return Err(Error::Serialization(anyhow::anyhow!(
"storage slot value has {} bytes; expected 32",
proto_slot.value.len()
)));
}
let slot = storage_slot_from_proto(proto_slot)?; Defensive patterns
Strategy: validation
Validate before calling
fn storage_slot_value_valid(slot: &ProtoStorageSlot) -> bool {
slot.value.len() == 32
} Type guard
fn is_bytes32(b: &[u8]) -> bool { b.len() == 32 } Try / catch
match storage_slot_from_proto(slot) {
Ok(s) => slots.push(s),
Err(Error::Serialization(ctx)) if ctx.to_string().contains("storage slot value") => {
tracing::warn!(value_len = slot.value.len(), "rejecting malformed storage slot");
return Err(Error::Serialization(ctx));
}
Err(e) => return Err(e),
} Prevention
- Validate both key and value lengths (32 bytes) for every storage slot before decoding.
- Use version-compatible encoders; re-encode from canonical on-chain data when in doubt.
- Roundtrip-test encoded blocks after any fuel-core upgrade.
When it happens
Trigger: fuel_block_from_protobuf on a block where some ProtoStorageSlot.value is empty or any non-32 length - corrupted blob, truncated frame, or a producer writing variable-length bytes for a fixed 32-byte field.
Common situations: Version-incompatible encoder; corruption on disk or in transit; test data with arbitrary-length byte vectors.
Related errors
- Could not convert storage slot key to Bytes32: {}
- Could not convert balance_root to Bytes32: {}
- Could not convert state_root to Bytes32: {}
- Could not convert return data digest to Bytes32: {}
- Could not convert log data digest to Bytes32: {}
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/47f0242356896f00.
Report an issue: GitHub.