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
- Re-encode the public key as pure hex (e.g. `hex::encode([u8; 32])`) and pass exactly 64 hex characters
- Strip any '0x' prefix, whitespace, or line breaks from the key string
- 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
- Store keys as hex in config and validate format at startup
- Strip '0x' prefixes and whitespace at config load time
- Add a unit test asserting your configured key passes hex decoding
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
- Invalid public key bytes
- Invalid signature hex encoding
- Invalid signature bytes
- Signature verification failed
- Invalid Ed25519 public key
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)