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
- No runtime action needed for normal library use — keys are validated at construction.
- If you build PublicKey from raw bytes outside the constructors, validate them first via VerifyingKey::from_bytes before wrapping.
- 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
- Only create PublicKey through its validated constructors (from bytes that parsed as a verifying key, or from_verifying_key).
- Never deserialize raw 32 bytes into PublicKey without ed25519 validation in forks/patches.
- If a panic with 'already verified' appears, audit the code path that produced the key bytes for truncation or corruption.
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)