Pumpkin-MC/Pumpkin · error · TelemetryVerificationError

Invalid public key bytes

Error message

Invalid public key bytes: {0}

What it means

TelemetryVerificationError::InvalidPublicKey(String), produced when the hex-decoded public key bytes cannot be converted into a valid Ed25519 public key (e.g. via VerifyingKey::from_bytes). Hex encoding was fine but the resulting 32 bytes are not a valid key or have the wrong length.

Solutions

  1. Pass the 32-byte Ed25519 public key (64 hex chars), not the private key or keypair
  2. Check the decoded byte length is exactly 32 before calling verify
  3. Regenerate the key pair with the same Ed25519 library and export the verifying/public key

Example fix

// before
let key = hex::encode(secret_key.to_bytes()); // 64 bytes -> 128 hex chars
// after
let key = hex::encode(secret_key.verifying_key().to_bytes()); // 32 bytes -> 64 hex chars
Defensive patterns

Strategy: validation

Validate before calling

let bytes = hex::decode(key)?;
if bytes.len() != 32 { return Err(format!("public key must be 32 bytes, got {}", bytes.len())); }

Type guard

fn valid_pubkey_bytes(key_hex: &str) -> bool {
    hex::decode(key_hex).map(|b| b.len() == 32).unwrap_or(false)
}

Try / catch

match telemetry::verify(&key, &sig, &msg, now) {
    Err(TelemetryVerificationError::InvalidPublicKey(m)) => log::error!("bad public key: {m}"),
    Ok(()) => { /* proceed */ }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling telemetry::verify with a hex string that decodes to something other than 32 bytes, or bytes rejected by the Ed25519 key constructor (wrong-length key material, e.g. 64-byte raw key or a private key blob).

Common situations: Passing an Ed25519 private key or a 64-byte sign/verify keypair blob instead of the 32-byte public key; pasting an RSA or X25519 key; truncated hex string.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09). Data as JSON: /api/errors/516a830f3f653616. Report an issue: GitHub.

Appendix: source

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

    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,
    body_bytes: &[u8],
    current_time_secs: u64,

View on GitHub (pinned to 8d4639e25a)