linera-io/linera-protocol · error
trailing data after log fields ({} unexpected bytes)
Error message
trailing data after log fields ({} unexpected bytes) What it means
decode_log enforces the log's declared payload boundary is consumed exactly: after address, topics list, and data string, log_data_buf must be empty (linera-bridge/src/proof/mod.rs:598). Trailing bytes mean the log list contains more than the three schema fields — a malformed log or a schema the parser does not know (e.g., a future EIP adding a fourth log field).
Source
Thrown at linera-bridge/src/proof/mod.rs:598
.map_err(|e| anyhow!("invalid topic: {e}"))?;
topics.push(topic);
}
// Decode log data (byte string)
let data_header = alloy_rlp::Header::decode(&mut log_data_buf)
.map_err(|e| anyhow!("invalid log data RLP: {e}"))?;
ensure!(
!data_header.list,
"log data must be a byte string, not a list"
);
ensure!(
log_data_buf.len() >= data_header.payload_length,
"log data extends past log boundary"
);
let log_bytes = log_data_buf[..data_header.payload_length].to_vec();
log_data_buf = &log_data_buf[data_header.payload_length..];
ensure!(
log_data_buf.is_empty(),
"trailing data after log fields ({} unexpected bytes)",
log_data_buf.len()
);
Ok(ReceiptLog {
address,
topics,
data: log_bytes,
})
}
#[cfg(test)]
mod tests {
#![allow(clippy::cast_possible_truncation)]
use std::str::FromStr;
View on GitHub (pinned to 6c226ddcb3)
Solutions
- Hex-dump the trailing bytes: recognizable structure (e.g., another RLP item) indicates a schema extension — check the chain's EIP/fork status and update the parser to decode or deliberately skip the new field.
- Confirm the receipt proof verifies against the header root; if it does, the extra bytes are protocol content, not corruption.
- If the bytes are garbage, re-fetch the node — likely provider corruption.
- Keep parser and chain-preset versions locked together when deploying the bridge scanner.
Example fix
// before
ensure!(log_data_buf.is_empty(), "trailing data after log fields ({} unexpected bytes)", log_data_buf.len());
// after (post-fork schema with an optional 4th field: skip instead of failing)
if !log_data_buf.is_empty() {
skip_rlp_item(&mut log_data_buf)?;
ensure!(log_data_buf.is_empty(), "more than one extra log field");
} Defensive patterns
Strategy: try-catch
Try / catch
match decode_receipt_logs(receipt_rlp) {
Ok(logs) => logs,
Err(e) if e.to_string().contains("trailing data after log fields") => {
tracing::warn!(error = %e, "unknown extra log fields (fork?); rejecting node pending parser update");
Vec::new()
}
Err(e) => return Err(e),
} Prevention
- Track hard-fork schedules of scanned chains; log-schema extensions require parser updates.
- Verify the proof before parsing so trailing bytes can be attributed to protocol vs corruption.
- Pin scanner and chain-preset versions together in deployment.
When it happens
Trigger: Decoding logs from a chain whose log entries carry extra fields beyond (address, topics, data); a corrupt node whose payload length overstates the content; fixtures that append extra bytes inside the log list.
Common situations: A hard fork extends the log schema and old parser binaries scan post-fork blocks; hand-built test logs with stray padding; trie nodes from an incompatible chain preset.
Related errors
- not enough data to skip RLP item
- log must be an RLP list
- log payload extends past available data
- topics must be an RLP list
- topics payload extends past log boundary
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/4594970731bb3116.
Report an issue: GitHub.