nautechsystems/nautilus_trader · error

Blockchain address '{address}' has incorrect checksum

Error message

Blockchain address '{address}' has incorrect checksum

What it means

After successfully parsing the hex, validate_address additionally checks the EIP-55 mixed-case checksum via Address::parse_checksummed. This error means the address is a well-formed 20-byte hex string, but its letter casing does not match the EIP-55 checksum — typically because the address was lowercased/uppercased after being generated, or contains a typo that breaks the keccak-based checksum.

Source

Thrown at crates/model/src/defi/validation.rs:47

///
/// This function returns an error if:
/// - The address does not start with the `0x` prefix.
/// - The address has invalid length (must be 42 characters including `0x`).
/// - The address contains invalid hexadecimal characters.
/// - The address has an incorrect checksum (for checksummed addresses).
pub fn validate_address(address: &str) -> anyhow::Result<Address> {
    // Check if the address starts with "0x"
    if !address.starts_with("0x") {
        anyhow::bail!("Ethereum address must start with '0x': {address}");
    }

    // Check if the address is valid
    let parsed_address = Address::from_str(address)
        .map_err(|e| anyhow::anyhow!("Blockchain address '{address}' is incorrect: {e}"))?;

    // Check if checksum is valid
    Address::parse_checksummed(address, None)
        .map_err(|_| anyhow::anyhow!("Blockchain address '{address}' has incorrect checksum"))?;

    Ok(parsed_address)
}

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

    use super::*;

    #[rstest]
    fn test_validate_address_invalid_prefix() {
        let invalid_address = "742d35Cc6634C0532925a3b844Bc454e4438f44e";
        let result = validate_address(invalid_address);
        assert!(result.is_err());
        assert_eq!(
            result.unwrap_err().to_string(),
            "Ethereum address must start with '0x': 742d35Cc6634C0532925a3b844Bc454e4438f44e"

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use a fully lowercase or fully uppercase address — all-lowercase is accepted since EIP-55 only constrains mixed-case strings.
  2. Restore the original checksummed form from a trusted source (block explorer, wallet).
  3. Recompute the EIP-55 checksum (e.g. via a checksum tool or alloy's to_checksum) and use that string.
  4. If the address must stay mixed-case, verify each character against the explorer — a checksum failure often indicates a typo.

Example fix

// before
let addr = validate_address("0x742d35Cc6634C0532925a3b844Bc454e4438f44e")?; // checksum broken by edit
// after
let addr = validate_address(&address.to_lowercase())?; // or use the exact checksummed form from the explorer
Defensive patterns

Strategy: validation

Validate before calling

fn is_checksummed_or_uniform(s: &str) -> bool {
    let body = &s[2..];
    body.chars().all(|c| !c.is_ascii_alphabetic()) // all-lower/upper digits-only is trivially safe
        || body.chars().any(|c| c.is_ascii_lowercase()) && body.chars().any(|c| c.is_ascii_uppercase())
        // otherwise verify via Address::parse_checksummed
}

Try / catch

match validate_address(addr) {
    Ok(a) => a,
    Err(e) if e.to_string().contains("incorrect checksum") => {
        // normalize and retry
        validate_address(&addr.to_lowercase())
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling validate_address with a mixed-case address string whose EIP-55 checksum does not match (common after to_lowercase()/to_uppercase() was applied to a checksummed address, or a hand-typed address).

Common situations: Config files where an address was normalized to lowercase by tooling then partially retyped; copy-paste from a source that changed casing; addresses compared case-insensitively somewhere and the mixed-case variant reconstructed by hand.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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