{"record":{"id":"28b6b8b26d5bed7b","repo":"nautechsystems/nautilus_trader","slug":"blockchain-address-address-has-incorrect-check","errorCode":null,"errorMessage":"Blockchain address '{address}' has incorrect checksum","messagePattern":"Blockchain address '(.+?)' has incorrect checksum","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/validation.rs","lineNumber":47,"sourceCode":"///\n/// This function returns an error if:\n/// - The address does not start with the `0x` prefix.\n/// - The address has invalid length (must be 42 characters including `0x`).\n/// - The address contains invalid hexadecimal characters.\n/// - The address has an incorrect checksum (for checksummed addresses).\npub fn validate_address(address: &str) -> anyhow::Result<Address> {\n    // Check if the address starts with \"0x\"\n    if !address.starts_with(\"0x\") {\n        anyhow::bail!(\"Ethereum address must start with '0x': {address}\");\n    }\n\n    // Check if the address is valid\n    let parsed_address = Address::from_str(address)\n        .map_err(|e| anyhow::anyhow!(\"Blockchain address '{address}' is incorrect: {e}\"))?;\n\n    // Check if checksum is valid\n    Address::parse_checksummed(address, None)\n        .map_err(|_| anyhow::anyhow!(\"Blockchain address '{address}' has incorrect checksum\"))?;\n\n    Ok(parsed_address)\n}\n\n#[cfg(test)]\nmod tests {\n    use rstest::rstest;\n\n    use super::*;\n\n    #[rstest]\n    fn test_validate_address_invalid_prefix() {\n        let invalid_address = \"742d35Cc6634C0532925a3b844Bc454e4438f44e\";\n        let result = validate_address(invalid_address);\n        assert!(result.is_err());\n        assert_eq!(\n            result.unwrap_err().to_string(),\n            \"Ethereum address must start with '0x': 742d35Cc6634C0532925a3b844Bc454e4438f44e\"","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/validation.rs#L29-L65","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Use a fully lowercase or fully uppercase address — all-lowercase is accepted since EIP-55 only constrains mixed-case strings.","Restore the original checksummed form from a trusted source (block explorer, wallet).","Recompute the EIP-55 checksum (e.g. via a checksum tool or alloy's to_checksum) and use that string.","If the address must stay mixed-case, verify each character against the explorer — a checksum failure often indicates a typo."],"exampleFix":"// before\nlet addr = validate_address(\"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\")?; // checksum broken by edit\n// after\nlet addr = validate_address(&address.to_lowercase())?; // or use the exact checksummed form from the explorer","handlingStrategy":"validation","validationCode":"fn is_checksummed_or_uniform(s: &str) -> bool {\n    let body = &s[2..];\n    body.chars().all(|c| !c.is_ascii_alphabetic()) // all-lower/upper digits-only is trivially safe\n        || body.chars().any(|c| c.is_ascii_lowercase()) && body.chars().any(|c| c.is_ascii_uppercase())\n        // otherwise verify via Address::parse_checksummed\n}","typeGuard":null,"tryCatchPattern":"match validate_address(addr) {\n    Ok(a) => a,\n    Err(e) if e.to_string().contains(\"incorrect checksum\") => {\n        // normalize and retry\n        validate_address(&addr.to_lowercase())\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Store addresses fully lowercase in configs and codebases","Never hand-edit a mixed-case address; recompute EIP-55 via to_checksum when needed","A checksum error frequently indicates a typo — cross-check with a block explorer"],"tags":["rust","ethereum","address","eip55","checksum"],"backgroundTag":"checksum-mismatch","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}