nautechsystems/nautilus_trader · error
SetFeeProtocol event data is too short
Error message
SetFeeProtocol event data is too short
What it means
In the Hypersync parsing path for PancakeSwap V3 `SetFeeProtocol` events, the log's `data` payload is length-checked against 4 words (4 * 32 = 128 bytes) before ABI decoding; if it is shorter, the parser bails with this message. The SetFeeProtocol event data is two 32-byte words plus padding, so a shorter payload means the log is corrupt, truncated, or was not actually a SetFeeProtocol event.
Source
Thrown at crates/adapters/blockchain/src/exchanges/parsing/pancakeswap_v3/fee_protocol_update.rs:67
///
/// # Panics
///
/// Panics if the contract address is not set in the log.
pub fn parse_fee_protocol_update_event_hypersync(
dex: SharedDex,
log: &HypersyncLog,
) -> anyhow::Result<FeeProtocolUpdateEvent> {
validate_event_signature_hash(
"SetFeeProtocolEvent",
FEE_PROTOCOL_UPDATE_EVENT_SIGNATURE_HASH,
log,
)?;
if let Some(data) = &log.data {
let data_bytes = data.as_ref();
if data_bytes.len() < 4 * 32 {
anyhow::bail!("SetFeeProtocol event data is too short");
}
let decoded = match <SetFeeProtocolEventData as SolType>::abi_decode(data_bytes) {
Ok(decoded) => decoded,
Err(e) => anyhow::bail!("Failed to decode SetFeeProtocol 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(FeeProtocolUpdateEvent::new(
dex,
pool_identifier,View on GitHub (pinned to 18893faf8b)
Solutions
- Filter the Hypersync query by the exact SetFeeProtocol topic0 signature so only genuine SetFeeProtocol logs reach the parser.
- Before parsing, check `log.data.as_ref().map(|d| d.len()).unwrap_or(0) >= 128` and skip logs that fail.
- Verify the target contract is a stock PancakeSwap V3 pool whose SetFeeProtocol ABI matches `SetFeeProtocolEventData` (2 params, non-indexed).
- Log the offending log's address/tx hash to identify the emitting contract and exclude it if it is a non-standard fork.
Example fix
// before
if let Some(data) = &log.data {
let decoded = <SetFeeProtocolEventData as SolType>::abi_decode(data.as_ref())?;
// after
if let Some(data) = &log.data {
if data.as_ref().len() < 4 * 32 {
tracing::warn!("skipping short SetFeeProtocol log (len={})", data.as_ref().len());
return Ok(None);
}
let decoded = <SetFeeProtocolEventData as SolType>::abi_decode(data.as_ref())?; Defensive patterns
Strategy: validation
Validate before calling
// before calling parse_fee_protocol_update_event_hypersync
let data_len = log.data.as_ref().map(|d| d.as_ref().len()).unwrap_or(0);
if data_len < 128 {
tracing::warn!("SetFeeProtocol log data too short: {data_len}");
return Ok(None);
} Type guard
fn is_valid_set_fee_protocol_log(log: &HyperSyncLog) -> bool {
log.topic0.as_deref() == Some(SET_FEE_PROTOCOL_TOPIC)
&& log.data.as_ref().map(|d| d.as_ref().len()).unwrap_or(0) >= 128
} Try / catch
match parse_fee_protocol_update_event_hypersync(dex, &log) {
Ok(ev) => store(ev),
Err(e) if e.to_string().contains("too short") => {
tracing::warn!("skipping malformed SetFeeProtocol log");
}
Err(e) => return Err(e),
} Prevention
- Always filter Hypersync queries by the exact SetFeeProtocol topic0 hash.
- Sanity-check data length (>= 128 bytes) at the ingestion boundary.
- Keep SetFeeProtocolEventData in sync with the deployed contract ABI version.
- Log the offending log's tx hash/address to trace non-standard contracts.
When it happens
Trigger: Calling `parse_fee_protocol_update_event_hypersync` with a Hypersync log whose `data` field contains fewer than 128 bytes — e.g. a mis-filtered log (wrong topic0 in the query), a zero-length/empty data field, or a truncated payload from the provider.
Common situations: A Hypersync query whose topic0 filter accidentally matches logs with a different data layout; logs from a forked/modified PancakeSwap V3 deployment with a different event signature; provider-side data truncation; running the parser against logs fetched without the data column populated correctly.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Failed to decode SetFeeProtocol event data: {e}
- RPC parsing of SetFeeProtocol event is not defined in this d
- RPC parsing of CollectProtocol event is not defined in this
- Missing data in SetFeeProtocol event log
- RPC parsing of initialize event is not defined in this dex:
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b4046019262a334e.
Report an issue: GitHub.