nautechsystems/nautilus_trader · error

Invalid event signature for '{event_name}': expected {expect

Error message

Invalid event signature for '{event_name}': expected {expected_hex}, was {actual_hex}

What it means

validate_signature_bytes compares the event signature topic bytes (hex-encoded) against the expected keccak256 signature hash for the named event and throws when they differ. This catches decoding a log that is not actually the event the caller assumed, preventing misparsed fields.

Source

Thrown at crates/adapters/blockchain/src/exchanges/parsing/core.rs:90

    Ok(i32::from_be_bytes(bytes[28..32].try_into()?))
}

/// Validate event signature matches expected hash.
///
/// The first topic (topic0) of an Ethereum event log contains the keccak256 hash
/// of the event signature. This function validates that the actual signature
/// matches the expected one.
///
/// # Errors
///
/// Returns an error if the signatures don't match.
pub fn validate_signature_bytes(
    actual: &[u8],
    expected_hex: &str,
    event_name: &str,
) -> anyhow::Result<()> {
    let actual_hex = hex::encode(actual);
    anyhow::ensure!(
        actual_hex == expected_hex,
        "Invalid event signature for '{event_name}': expected {expected_hex}, was {actual_hex}",
    );
    Ok(())
}

#[cfg(test)]
mod tests {
    use rstest::rstest;

    use super::*;

    #[rstest]
    fn test_extract_address_token0() {
        // token0 address from PoolCreated event topic1 at block 185
        let bytes = hex::decode("0000000000000000000000002e5353426c89f4ecd52d1036da822d47e73376c4")
            .unwrap();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Compare the actual hex in the error with the keccak256 of the event signature you intended; correct expected_hex or route the log to the right parser
  2. Verify topic0 is the signature topic (index 0), not a data or param topic
  3. Recompute the expected hash from the contract's ABI if it was recently upgraded
  4. Add explicit dispatch by topic0 before invoking the specific event parser

Example fix

// before
validate_signature_bytes(topic0, UNISWAP_V3_SWAP_SIG, "Swap")?;
// after
if hex::encode(topic0) == PANCAKE_V3_SWAP_SIG {
    validate_signature_bytes(topic0, PANCAKE_V3_SWAP_SIG, "Swap")?;
} else {
    return Err(anyhow::anyhow!("unsupported swap signature"));
}
Defensive patterns

Strategy: validation

Validate before calling

fn signature_matches(topic0: &[u8], expected_hex: &str) -> bool {
    hex::encode(topic0) == expected_hex
}

Try / catch

match validate_signature_bytes(topic0, EXPECTED_SWAP_SIG, "Swap") {
    Ok(()) => decode_swap(),
    Err(e) if e.to_string().contains("Invalid event signature") => route_to_correct_parser(topic0),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling validate_signature_bytes with the signature topic of a different event, e.g. passing an Uniswap V3 swap topic to a PancakeSwap V3 parser, or a wrong expected_hex constant; also when topic0 bytes are truncated so the hex never matches.

Common situations: Indexing multiple DEX forks whose events share names but different signatures (e.g. Uniswap V3 vs PancakeSwap V3 swap); a contract upgrade changed the event ABI; copy-pasted wrong expected hash.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/f1af5053728cedf7. Report an issue: GitHub.