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

  1. Verify the key string is the full, unpadded base32 encoding of 32 bytes (52 characters).
  2. Strip any '=' padding and whitespace before parsing.
  3. Check you are not passing a hex-encoded key where base32 is expected (or vice versa); the parser auto-detects via 0x prefix / charset.
  4. 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

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)