n0-computer/iroh · info

already verified

Error message

already verified

What it means

PublicKey::as_verifying_key converts the stored compressed Edwards-Y point into an ed25519-dalek VerifyingKey with VerifyingKey::from_bytes(...).expect("already verified"). from_bytes only fails for malformed points; since every PublicKey is constructed from bytes already validated as a canonical Ed25519 point, the conversion cannot fail. The expect asserts that invariant.

Solutions

  1. No runtime action needed for normal library use — keys are validated at construction.
  2. If you build PublicKey from raw bytes outside the constructors, validate them first via VerifyingKey::from_bytes before wrapping.
  3. When refactoring key construction paths, route all input through the existing validated constructors (from_bytes / from_verifying_key).
Defensive patterns

Strategy: validation

Validate before calling

// If constructing key material yourself, validate before wrapping into PublicKey
fn valid_pubkey(bytes: &[u8]) -> bool {
    use ed25519_dalek::VerifyingKey;
    <&[u8; 32]>::try_from(bytes).map(|b| VerifyingKey::from_bytes(b).is_ok()).unwrap_or(false)
}

Prevention

When it happens

Trigger: Not reachable via the public API: PublicKey values come from verified 32-byte Ed25519 keys (from bytes or verifying keys), so from_bytes cannot reject them. Would only fire if a PublicKey were built from unvalidated raw bytes.

Common situations: Appears during code review or when constructing PublicKey directly from raw bytes in a fork/patch; a panic here means a PublicKey was created from non-canonical or truncated key material somewhere upstream.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of n0-computer/iroh@2b4de030ce (2026-09-08). Data as JSON: /api/errors/6298355194628f65. Report an issue: GitHub.

Appendix: source

Thrown at iroh-base/src/key.rs:153

        self.as_verifying_key()
            .verify_strict(message, &signature.0)
            .map_err(|_| SignatureError::new())
    }

    /// Convert to a hex string limited to the first 5 bytes for a friendly string
    /// representation of the key.
    pub fn fmt_short(&self) -> impl Display + Copy + 'static {
        PublicKeyShort(
            self.0.as_bytes()[0..5]
                .try_into()
                .expect("slice with incorrect length"),
        )
    }

    /// Needed for internal conversions, not part of the stable API.
    #[doc(hidden)]
    pub fn as_verifying_key(&self) -> VerifyingKey {
        VerifyingKey::from_bytes(self.0.as_bytes()).expect("already verified")
    }

    /// Needed for internal conversions, not part of the stable API.
    #[doc(hidden)]
    pub fn from_verifying_key(key: VerifyingKey) -> Self {
        Self(CompressedEdwardsY(key.to_bytes()))
    }

    /// Encodes this key in [z-base-32](https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt),
    /// the encoding used by [pkarr](https://pkarr.org) domain names.
    pub fn to_z32(&self) -> String {
        Z_BASE_32.encode(self.as_bytes())
    }

    /// Parses a key from its [z-base-32](https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt) encoding.
    pub fn from_z32(s: &str) -> Result<Self, KeyParsingError> {
        let bytes = Z_BASE_32
            .decode(s.as_bytes())

View on GitHub (pinned to 2b4de030ce)