{"record":{"id":"64b402bc5615433b","repo":"n0-computer/iroh","slug":"invalidlength","errorCode":"InvalidLength","errorMessage":"invalid length","messagePattern":"invalid length","errorType":"validation","errorClass":"KeyParsingError","httpStatus":null,"severity":"error","filePath":"iroh-base/src/key.rs","lineNumber":487,"sourceCode":"\n/// Verification of a signature failed.\n#[stack_error(derive, add_meta)]\n#[error(\"Invalid signature\")]\npub struct SignatureError {}\n\nfn decode_base32_hex(s: &str) -> Result<[u8; 32], KeyParsingError> {\n    let mut bytes = [0u8; 32];\n\n    let len = if s.len() == PublicKey::LENGTH * 2 {\n        // hex\n        data_encoding::HEXLOWER\n            .decode_mut(s.as_bytes(), &mut bytes)\n            .map_err(|_| e!(KeyParsingError::FailedToDecodeHex))?\n    } else {\n        let input = s.to_ascii_uppercase();\n        let input = input.as_bytes();\n        ensure!(\n            data_encoding::BASE32_NOPAD.decode_len(input.len()) == Ok(bytes.len()),\n            KeyParsingError::InvalidLength\n        );\n        data_encoding::BASE32_NOPAD\n            .decode_mut(input, &mut bytes)\n            .map_err(|_| e!(KeyParsingError::FailedToDecodeBase32))?\n    };\n    ensure!(len == PublicKey::LENGTH, KeyParsingError::InvalidLength);\n    Ok(bytes)\n}\n\n#[cfg(test)]\nmod tests {\n    use data_encoding::HEXLOWER;\n    use rand::{RngExt, SeedableRng};\n\n    use super::*;\n\n    #[test]","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/n0-computer/iroh/blob/2b4de030ce5e0133f272871a76f0c685c63f552a/iroh-base/src/key.rs#L469-L505","documentation":"KeyParsingError::InvalidLength from iroh-base's decode_base32_hex (used by PublicKey::from_str). Before decoding, the code verifies that BASE32_NOPAD.decode_len(input.len()) equals the expected byte buffer length (32). If the base32 string's length cannot decode to exactly 32 bytes, this error is thrown — the string has the wrong length for a public key.","triggerScenarios":"Parsing a node/public key id via FromStr where the string is base32 (non-hex) and its length is not the canonical encoded length for 32 bytes (e.g. truncated, padded, or overly long key strings).","commonSituations":"Copy-pasted key strings that lost characters; keys with base32 '=' padding included; user-supplied node IDs in config files or CLI args; confusing hex-formatted keys with base32 ones.","solutions":["Verify the key string is the full, unpadded base32 encoding of 32 bytes (52 characters).","Strip any '=' padding and whitespace before parsing.","Check you are not passing a hex-encoded key where base32 is expected (or vice versa); the parser auto-detects via 0x prefix / charset.","Regenerate or re-copy the key from its source (e.g. iroh console output or DNS discovery record)."],"exampleFix":"// before\nlet key: PublicKey = short_or_padded_str.parse()?; // InvalidLength\n// after\nlet s = short_or_padded_str.trim().trim_end_matches('=');\nif s.len() != 52 { return Err(\"expected 52-char base32 node id\"); }\nlet key: PublicKey = s.parse()?;","handlingStrategy":"validation","validationCode":"fn is_valid_node_id_str(s: &str) -> bool {\n    let s = s.trim().trim_end_matches('=');\n    s.len() == 52 && s.chars().all(|c| c.is_ascii_alphanumeric())\n}","typeGuard":null,"tryCatchPattern":"match s.parse::<PublicKey>() {\n    Ok(k) => k,\n    Err(e) if format!(\"{e}\").contains(\"invalid length\") => Err(\"node id must be a 52-char base32 string\"),\n    Err(e) => Err(e.into()),\n}","preventionTips":["Copy full key strings; never truncate or hand-edit them","Strip whitespace and '=' padding before parsing","Display keys via their Display impl, not slicing","Validate length (52 chars) in UIs/CLIs before calling parse"],"tags":["keys","base32","parsing","validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"2b4de030ce5e0133f272871a76f0c685c63f552a","analyzedAt":"2026-09-08T04:26:47.755Z","contentChangedAt":"2026-09-08T04:26:47.755Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}