n0-computer/iroh · error · KeyParsingError
InvalidLength
InvalidLength
Error message
invalid length
What it means
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.
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).
Example fix
// before
let key: PublicKey = short_or_padded_str.parse()?; // InvalidLength
// after
let s = short_or_padded_str.trim().trim_end_matches('=');
if s.len() != 52 { return Err("expected 52-char base32 node id"); }
let key: PublicKey = s.parse()?; Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_node_id_str(s: &str) -> bool {
let s = s.trim().trim_end_matches('=');
s.len() == 52 && s.chars().all(|c| c.is_ascii_alphanumeric())
} Try / catch
match s.parse::<PublicKey>() {
Ok(k) => k,
Err(e) if format!("{e}").contains("invalid length") => Err("node id must be a 52-char base32 string"),
Err(e) => Err(e.into()),
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of n0-computer/iroh@2b4de030ce (2026-09-08).
Data as JSON: /api/errors/64b402bc5615433b.
Report an issue: GitHub.
Appendix: source
Thrown at iroh-base/src/key.rs:487
/// Verification of a signature failed.
#[stack_error(derive, add_meta)]
#[error("Invalid signature")]
pub struct SignatureError {}
fn decode_base32_hex(s: &str) -> Result<[u8; 32], KeyParsingError> {
let mut bytes = [0u8; 32];
let len = if s.len() == PublicKey::LENGTH * 2 {
// hex
data_encoding::HEXLOWER
.decode_mut(s.as_bytes(), &mut bytes)
.map_err(|_| e!(KeyParsingError::FailedToDecodeHex))?
} else {
let input = s.to_ascii_uppercase();
let input = input.as_bytes();
ensure!(
data_encoding::BASE32_NOPAD.decode_len(input.len()) == Ok(bytes.len()),
KeyParsingError::InvalidLength
);
data_encoding::BASE32_NOPAD
.decode_mut(input, &mut bytes)
.map_err(|_| e!(KeyParsingError::FailedToDecodeBase32))?
};
ensure!(len == PublicKey::LENGTH, KeyParsingError::InvalidLength);
Ok(bytes)
}
#[cfg(test)]
mod tests {
use data_encoding::HEXLOWER;
use rand::{RngExt, SeedableRng};
use super::*;
#[test]View on GitHub (pinned to 2b4de030ce)