nautechsystems/nautilus_trader · error
Failed to decode burn event data: {e}
Error message
Failed to decode burn event data: {e} What it means
Raised by parse_burn_event_hypersync when alloy's ABI decoder fails to decode the Burn event data as BurnEventData, even though the 96-byte length check passed. The underlying alloy error is interpolated into the message. This means the bytes are long enough but do not match the Burn event ABI layout (types/values mismatch).
Source
Thrown at crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/burn.rs:89
Some(topic) => {
let tick_upper_bytes: [u8; 32] = topic.as_ref().try_into()?;
i32::from_be_bytes(tick_upper_bytes[28..32].try_into()?)
}
None => anyhow::bail!("Missing tickUpper in topic3 when parsing burn event"),
};
if let Some(data) = &log.data {
let data_bytes = data.as_ref();
// Validate if data contains 3 parameters of 32 bytes each
if data_bytes.len() < 3 * 32 {
anyhow::bail!("Burn event data is too short");
}
// Decode the data using the BurnEventData struct
let decoded = match <BurnEventData as SolType>::abi_decode(data_bytes) {
Ok(decoded) => decoded,
Err(e) => anyhow::bail!("Failed to decode burn event data: {e}"),
};
let pool_address = Address::from_slice(
log.address
.clone()
.expect("Contract address should be set in logs")
.as_ref(),
);
let pool_identifier = PoolIdentifier::Address(Ustr::from(&pool_address.to_string()));
Ok(BurnEvent::new(
dex,
pool_identifier,
extract_block_number(log)?,
extract_transaction_hash(log)?,
extract_transaction_index(log)?,
extract_log_index(log)?,
owner,
tick_lower,View on GitHub (pinned to 18893faf8b)
Solutions
- Log the full {e} from the bail plus the data hex to identify the exact decoding failure (offset/length mismatch, invalid value)
- Verify the topic0 filter matches the exact Burn event signature hash so only Burn-event data reaches the decoder
- Check the BurnEventData type in the contract bindings matches the pool contract version actually emitting the log (regenerate bindings with alloy if the ABI changed)
- Inspect the raw log's data field against the expected Burn layout (uint128 amount, uint256 amount0, uint256 amount1) on a block explorer
Example fix
// before
Err(e) => anyhow::bail!("Failed to decode burn event data: {e}"),
// after (caller-side diagnostic + skip)
match parse_burn_event_hypersync(log) {
Ok(ev) => { /* use ev */ }
Err(e) if e.to_string().contains("Failed to decode burn event data") => {
tracing::warn!(data = ?log.data, "non-Burn data layout; skipping: {e:#}");
return Ok(None);
}
Err(e) => return Err(e),
} Defensive patterns
Strategy: try-catch
Validate before calling
fn plausible_burn_data(data: &[u8]) -> bool {
data.len() == 96 && data.iter().all(|b| true) // length exact; deep check via re-encoding
}
// optionally re-encode the decoded struct and compare bytes to detect layout drift Try / catch
match parse_burn_event_hypersync(&log) {
Ok(ev) => handle(ev),
Err(e) if e.to_string().contains("Failed to decode burn event data") => {
tracing::warn!(e = %e, data = ?log.data, "ABI decode failed; quarantining log");
}
Err(e) => return Err(e.into()),
} Prevention
- Regenerate alloy bindings whenever the pool contract ABI changes
- Log the full error chain ({e:#}) and raw data hex on decode failure
- Pin the provider/contract version and verify topic0 hash against the Burn signature
- Add round-trip tests: abi_encode(BurnEventData) then abi_decode must succeed
When it happens
Trigger: Calling parse_burn_event_hypersync with data whose 96+ bytes do not decode as BurnEventData — e.g. data from a different event type with a similar shape, byte-swapped or truncated-but-padded data, or data encoded for an older/other contract version.
Common situations: Wrong topic filter capturing another event with 4 topics and >=96 data bytes; data hex string decoded with wrong endianness or with non-hex characters stripped in fixtures; a contract upgrade changing the data layout; corrupted payloads from a third-party indexer.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Collect event data is too short
- Failed to decode collect event data: {e}
- Failed to decode CollectProtocol event data: {e}
- Finalized transaction {} emitted {} Swap logs; expected exac
- {type_name} raw value {raw} exceeds {raw_max_name}={raw_max}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/afce8cc09815fc1d.
Report an issue: GitHub.