Pumpkin-MC/Pumpkin · error · AuthError

x5u not found in header

Error message

x5u not found in header

What it means

AuthError::MissingX5U from the pumpkin-auth JWT module, thrown when a JWT being verified lacks the 'x5u' (X.509 URL) header parameter. Pumpkin uses x5u to locate the public key certificate needed to validate the signature; without it verification cannot proceed.

Solutions

  1. Decode the token header (base64) and confirm it contains an 'x5u' field before verifying
  2. Use tokens issued through the proper Mojang/Xbox authentication chain, which include x5u
  3. If testing locally, construct tokens with an x5u header pointing at (or matching) your public key
  4. Do not strip or rewrite JWT headers in proxies/middleware

Example fix

// before
let header = json!({"alg": "RS256"}); // no x5u
// after
let header = json!({"alg": "RS256", "x5u": public_key_url});
Defensive patterns

Strategy: type-guard

Validate before calling

let header_b64 = token.split('.').next().unwrap_or("");
let header: serde_json::Value = serde_json::from_slice(&URL_SAFE_NO_PAD.decode(header_b64)?)?;
if header.get("x5u").is_none() { return Err("JWT header missing x5u"); }

Type guard

fn has_x5u(token: &str) -> bool {
    token.split('.').next()
        .and_then(|h| base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(h).ok())
        .and_then(|b| serde_json::from_slice::<serde_json::Value>(&b).ok())
        .map(|v| v.get("x5u").is_some())
        .unwrap_or(false)
}

Try / catch

match jwt::verify(token) {
    Err(AuthError::MissingX5U) => { log::warn!("token header lacks x5u; non-Mojang issuer?"); reject_handshake(); }
    Ok(claims) => { /* proceed */ }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Verifying a JWT whose header JSON contains no 'x5u' field — e.g. a self-signed or third-party JWT, or a token whose header was replaced/stripped in transit.

Common situations: Client sends a token minted by a non-Mojang issuer that omits x5u; middleware re-encodes the JWT header and drops custom claims; testing with locally generated tokens that don't mimic Mojang token structure.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at crates/pumpkin-auth/src/jwt/mod.rs:36

/// This struct contains the player's display name, UUID, and XUID.
#[derive(Debug)]
pub struct PlayerClaims {
    /// The player's display name (in-game name).
    pub display_name: String,
    /// The player's unique identifier (UUID).
    pub uuid: String,
    /// The player's Xbox User ID (XUID).
    pub xuid: String,
}

/// Represents the possible errors that can occur during JWT verification.
#[derive(Debug, Error)]
pub enum AuthError {
    /// Indicates that a JWT token has an invalid format (not enough parts).
    #[error("Invalid token format")]
    InvalidTokenFormat,
    /// Indicates that the 'x5u' (X.509 URL) header parameter is missing from a token.
    #[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}")]

View on GitHub (pinned to 8d4639e25a)