linera-io/linera-protocol · error
failed to skip receipt field {i}: {e}
Error message
failed to skip receipt field {i}: {e} What it means
While walking the receipt prefix, skip_rlp_item failed on one of the first three fields (status, cumulative_gas_used, logs_bloom) — the field index i in the message says which. The bytes at that cursor are not a valid RLP item header, so the receipt prefix is malformed or truncated.
Source
Thrown at linera-bridge/src/proof/mod.rs:397
// EIP-2718: if first byte < 0x80, it's a transaction type prefix
if data[0] < 0x80 {
data = &data[1..];
}
let list_header =
alloy_rlp::Header::decode(&mut data).map_err(|e| anyhow!("invalid receipt RLP: {e}"))?;
ensure!(list_header.list, "receipt must be an RLP list");
// Limit reads to the receipt's declared payload.
ensure!(
data.len() >= list_header.payload_length,
"receipt payload extends past available data"
);
let mut data = &data[..list_header.payload_length];
// Skip: status (0), cumulative_gas_used (1), logs_bloom (2)
for i in 0..3 {
skip_rlp_item(&mut data).map_err(|e| anyhow!("failed to skip receipt field {i}: {e}"))?;
}
// Decode the logs list
let logs_header =
alloy_rlp::Header::decode(&mut data).map_err(|e| anyhow!("invalid logs list RLP: {e}"))?;
ensure!(logs_header.list, "logs must be an RLP list");
ensure!(
data.len() >= logs_header.payload_length,
"logs payload extends past receipt boundary"
);
let mut logs_data = &data[..logs_header.payload_length];
let mut logs = Vec::new();
while !logs_data.is_empty() {
logs.push(decode_log(&mut logs_data)?);
}
Ok(logs)View on GitHub (pinned to 6c226ddcb3)
Solutions
- Re-derive the receipt bytes from a trusted source (RPC receipt re-encoded via Encodable2718)
- Check the field order: status, cumulativeGasUsed, bloom, then logs
- Verify the buffer length covers the declared payload (the prior 'extends past available data' check passed, so the corruption is inside the payload)
Defensive patterns
Strategy: try-catch
Try / catch
match decode_receipt_logs(&receipt_rlp) {
Err(e) if e.to_string().contains("failed to skip receipt field") => {
// receipt prefix malformed: re-fetch and re-encode the receipt instead of patching bytes
}
other => other?,
} Prevention
- Use complete receipt bytes from a trusted re-encoding path
- In tests, build receipts with the crate's build_test_receipt helpers
- Field order is status, cumulativeGasUsed, bloom, logs — never reorder fixtures
When it happens
Trigger: decode_receipt_logs on a receipt whose prefix is truncated (buffer ends mid-field), where a field starts with an invalid length prefix, or where a field that must be a single byte is a long string/list.
Common situations: Truncated receipt bytes from bad hex decoding or storage; hand-crafted receipt fixtures with wrong field ordering; feeding envelope bytes that skip the type byte incorrectly.
Related errors
- invalid receipt RLP: {e}
- invalid logs list RLP: {e}
- invalid RLP item: {e}
- invalid log RLP: {e}
- receipt must be an RLP list
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/2ebd3bc2e551a909.
Report an issue: GitHub.