Pumpkin-MC/Pumpkin · error · TelemetryVerificationError

Invalid public key hex encoding

Error message

Invalid public key hex encoding

What it means

TelemetryVerificationError::InvalidPublicKeyHex, produced by the telemetry signature verifier when the caller-supplied Ed25519 public key cannot be parsed as a hex string. The library expects the key to be encoded as lowercase/uppercase hexadecimal (64 hex chars for 32 bytes). It is thrown before any signature verification happens.

Solutions

  1. Re-encode the public key as pure hex (e.g. `hex::encode([u8; 32])`) and pass exactly 64 hex characters
  2. Strip any '0x' prefix, whitespace, or line breaks from the key string
  3. Confirm the key source (config file, env var) actually holds an Ed25519 public key in hex format

Example fix

// before
let key = "MCowBQYDK2VwAyEA..."; // base64 PEM body
// after
let key = "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; // hex
Defensive patterns

Strategy: validation

Validate before calling

fn is_hex(s: &str) -> bool { !s.is_empty() && s.len() % 2 == 0 && s.bytes().all(|b| b.is_ascii_hexdigit()) }
if !is_hex(key.trim()) { return Err("public key must be pure hex"); }

Type guard

fn valid_pubkey_hex(s: &str) -> bool {
    let t = s.trim().trim_start_matches("0x");
    t.len() == 64 && t.bytes().all(|b| b.is_ascii_hexdigit())
}

Try / catch

match telemetry::verify(&key, &sig, &msg, now) {
    Err(TelemetryVerificationError::InvalidPublicKeyHex) => log::warn!("key is not hex: reject config"),
    Ok(()) => { /* proceed */ }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling telemetry::verify with a public key string containing non-hex characters, an odd number of characters, or whitespace/prefixes like '0x'.

Common situations: Config file holds a base64 key instead of hex; key was copied with a '0x' prefix or surrounding quotes/whitespace; key truncated or from the wrong crypto system.

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 Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09). Data as JSON: /api/errors/9786c39ea4dbcbe5. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin/src/telemetry.rs:127

    body_bytes: &[u8],
) -> (String, String) {
    let signed_data = compute_signed_data(timestamp_str, body_bytes);
    let signature = signing_key.sign(&signed_data);
    let pubkey_hex = hex::encode(signing_key.verifying_key().to_bytes());
    let sig_hex = hex::encode(signature.to_bytes());
    (pubkey_hex, sig_hex)
}

/// Errors that can occur during telemetry request signature verification.
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum TelemetryVerificationError {
    #[error("Invalid timestamp string format")]
    InvalidTimestamp,
    #[error(
        "Timestamp drift exceeded: drift was {drift}s (max allowed is {MAX_CLOCK_DRIFT_SECS}s)"
    )]
    ClockDriftExceeded { drift: u64 },
    #[error("Invalid public key hex encoding")]
    InvalidPublicKeyHex,
    #[error("Invalid public key bytes: {0}")]
    InvalidPublicKey(String),
    #[error("Invalid signature hex encoding")]
    InvalidSignatureHex,
    #[error("Invalid signature bytes: {0}")]
    InvalidSignature(String),
    #[error("Signature verification failed: {0}")]
    VerificationFailed(String),
}

/// Verifies a signed telemetry request against an Ed25519 public key and timestamp.
///
/// Ensures clock drift between `current_time_secs` and `timestamp_str` does not exceed `±300` seconds.
pub fn verify_telemetry_request(
    pubkey_hex: &str,
    sig_hex: &str,
    timestamp_str: &str,

View on GitHub (pinned to 8d4639e25a)