{"record":{"id":"451351bdd9627b39","repo":"Pumpkin-MC/Pumpkin","slug":"invalid-signature-bytes-0","errorCode":null,"errorMessage":"Invalid signature bytes: {0}","messagePattern":"Invalid signature bytes: (.+?)","errorType":"error_code","errorClass":"TelemetryVerificationError","httpStatus":null,"severity":"error","filePath":"crates/pumpkin/src/telemetry.rs","lineNumber":133,"sourceCode":"    (pubkey_hex, sig_hex)\n}\n\n/// Errors that can occur during telemetry request signature verification.\n#[derive(Debug, thiserror::Error, PartialEq, Eq)]\npub enum TelemetryVerificationError {\n    #[error(\"Invalid timestamp string format\")]\n    InvalidTimestamp,\n    #[error(\n        \"Timestamp drift exceeded: drift was {drift}s (max allowed is {MAX_CLOCK_DRIFT_SECS}s)\"\n    )]\n    ClockDriftExceeded { drift: u64 },\n    #[error(\"Invalid public key hex encoding\")]\n    InvalidPublicKeyHex,\n    #[error(\"Invalid public key bytes: {0}\")]\n    InvalidPublicKey(String),\n    #[error(\"Invalid signature hex encoding\")]\n    InvalidSignatureHex,\n    #[error(\"Invalid signature bytes: {0}\")]\n    InvalidSignature(String),\n    #[error(\"Signature verification failed: {0}\")]\n    VerificationFailed(String),\n}\n\n/// Verifies a signed telemetry request against an Ed25519 public key and timestamp.\n///\n/// Ensures clock drift between `current_time_secs` and `timestamp_str` does not exceed `±300` seconds.\npub fn verify_telemetry_request(\n    pubkey_hex: &str,\n    sig_hex: &str,\n    timestamp_str: &str,\n    body_bytes: &[u8],\n    current_time_secs: u64,\n) -> Result<(), TelemetryVerificationError> {\n    let ts: u64 = timestamp_str\n        .parse()\n        .map_err(|_| TelemetryVerificationError::InvalidTimestamp)?;","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin/src/telemetry.rs#L115-L151","documentation":"TelemetryVerificationError::InvalidSignature(String), produced when the hex-decoded signature bytes cannot be converted into an Ed25519 Signature (typically wrong length — Ed25519 signatures are 64 bytes). Hex decoding succeeded but the byte content is unusable.","triggerScenarios":"Calling telemetry::verify with a hex string decoding to a length other than 64 bytes — e.g. a truncated signature, a SHA-256 digest, or concatenated key+signature material.","commonSituations":"Signing implementation truncates or extends output; client signs with a different algorithm (e.g. ECDSA) than expected; middleware strips/reformats the signature.","solutions":["Verify the decoded signature is exactly 64 bytes before calling verify","Ensure the client signs with Ed25519 over the same payload the server verifies","Log the decoded byte length on failure to spot truncation in the transport layer"],"exampleFix":"// before\nlet sig_bytes = &sha256(payload); // 32 bytes\n// after\nlet sig_bytes = signing_key.sign(payload.as_bytes()).to_bytes(); // 64 bytes","handlingStrategy":"validation","validationCode":"let bytes = hex::decode(sig)?;\nif bytes.len() != 64 { return Err(format!(\"signature must be 64 bytes, got {}\", bytes.len())); }","typeGuard":"fn valid_signature_bytes(sig_hex: &str) -> bool {\n    hex::decode(sig_hex).map(|b| b.len() == 64).unwrap_or(false)\n}","tryCatchPattern":"match telemetry::verify(&key, &sig, &msg, now) {\n    Err(TelemetryVerificationError::InvalidSignature(m)) => log::error!(\"bad signature (len check failed): {m}\"),\n    Ok(()) => { /* proceed */ }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Use the Ed25519 crate's Signature::to_bytes() output directly (always 64 bytes)","Reject signatures with wrong decoded length at the HTTP layer with a clear 400 message","Log decoded byte lengths on failure to detect truncating middleware"],"tags":["rust","ed25519","signature","byte-length"],"backgroundTag":"invalid-argument-value","analyzedSha":"8d4639e25a57c15e47448ec327c780d41bbf2356","analyzedAt":"2026-09-09T15:32:22.916Z","contentChangedAt":"2026-09-09T15:32:22.916Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}