Pumpkin-MC/Pumpkin · error · AuthError
ECDSA signature error
Error message
ECDSA signature error: {0} What it means
This variant wraps an underlying ecdsa::Error from the `ecdsa` crate, covering low-level ECDSA signature operation failures during JWT verification. It is distinct from InvalidSignature: it signals malformed signature encoding or internal crypto errors rather than a simple verification mismatch.
Solutions
- Check the signature byte length and format (64-byte r||s vs DER) before constructing the Signature
- Log the wrapped ecdsa::Error to distinguish malformed encoding from verification failure
- Pin consistent versions of the p256/ecdsa crates; format handling changed across versions
- Treat as an auth failure and reject the client, since the signature cannot be processed
Example fix
// before
let sig = Signature::<NistP256>::from_slice(&sig_bytes)?;
// after
let sig = Signature::<NistP256>::from_slice(&sig_bytes)
.map_err(|e| {
log::warn!("client sent malformed ECDSA signature: {e}");
AuthError::Ecdsa(e)
})?; Defensive patterns
Strategy: try-catch
Validate before calling
// ECDSA P-256 signatures are 64 bytes (r || s)
fn signature_bytes_look_valid(sig: &[u8]) -> bool {
sig.len() == 64
} Type guard
fn is_raw_ecdsa_signature(sig: &[u8]) -> bool {
sig.len() == 64
} Try / catch
match jwt::verify(&token) {
Err(jwt::Error::Ecdsa(e)) => {
log::warn!("ECDSA operation failed on token: {e}; rejecting client");
}
r => r?,
} Prevention
- Check signature byte length (64 for raw r||s) before constructing a Signature
- Pin compatible p256/ecdsa crate versions in Cargo.toml
- Log the wrapped ecdsa::Error to separate encoding issues from trust issues
- Reject clients whose signatures cannot be parsed
When it happens
Trigger: Constructing a Signature from bytes of the wrong length/format, or calling sign/verify APIs where the ecdsa crate returns an operational error, during Mojang token validation.
Common situations: Tokens whose signature field is not exactly 64 bytes of r||s; corrupted DER-encoded signatures; using a crypto crate version whose signature format expectations changed.
Related errors
- Invalid signature
- Public key build failed
- Token not signed by trusted Mojang key
- Invalid signature hex encoding
- Invalid signature bytes
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/afd48f1b9c4e2df6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-auth/src/jwt/mod.rs:54
#[error("x5u not found in header")]
MissingX5U,
/// Indicates a failure in Base64 decoding.
#[error("Base64 decoding failed: {0}")]
Base64Decode(#[from] base64::DecodeError),
/// Indicates a failure in parsing JSON data.
#[error("JSON parse error: {0}")]
JsonParse(#[from] serde_json::Error),
/// Indicates a failure in building a public key from its representation.
#[error("Public key build failed: {0}")]
PublicKeyBuild(String),
/// Indicates that the token was not signed by the trusted Mojang public key.
#[error("Token not signed by trusted Mojang key")]
MojangKeyMismatch,
/// Indicates that the token's signature is invalid.
#[error("Invalid signature")]
InvalidSignature,
/// Indicates an error related to ECDSA signature operations.
#[error("ECDSA signature error: {0}")]
Ecdsa(#[from] ecdsa::Error),
}
/// Decodes a Base64 URL-safe encoded string with no padding.
///
/// # Arguments
///
/// * `s` - The Base64 URL-safe encoded string to decode.
///
/// # Returns
///
/// A `Result` containing the decoded bytes or a `base64::DecodeError`.
pub fn decode_b64_url_nopad(s: &str) -> Result<Vec<u8>, base64::DecodeError> {
general_purpose::URL_SAFE_NO_PAD.decode(s)
}
/// Decodes a standard Base64 encoded string.
///View on GitHub (pinned to 8d4639e25a)