{"record":{"id":"801c49b0e9146051","repo":"Pumpkin-MC/Pumpkin","slug":"x5u-not-found-in-header","errorCode":null,"errorMessage":"x5u not found in header","messagePattern":"x5u not found in header","errorType":"error_code","errorClass":"AuthError","httpStatus":null,"severity":"error","filePath":"crates/pumpkin-auth/src/jwt/mod.rs","lineNumber":36,"sourceCode":"/// This struct contains the player's display name, UUID, and XUID.\n#[derive(Debug)]\npub struct PlayerClaims {\n    /// The player's display name (in-game name).\n    pub display_name: String,\n    /// The player's unique identifier (UUID).\n    pub uuid: String,\n    /// The player's Xbox User ID (XUID).\n    pub xuid: String,\n}\n\n/// Represents the possible errors that can occur during JWT verification.\n#[derive(Debug, Error)]\npub enum AuthError {\n    /// Indicates that a JWT token has an invalid format (not enough parts).\n    #[error(\"Invalid token format\")]\n    InvalidTokenFormat,\n    /// Indicates that the 'x5u' (X.509 URL) header parameter is missing from a token.\n    #[error(\"x5u not found in header\")]\n    MissingX5U,\n    /// Indicates a failure in Base64 decoding.\n    #[error(\"Base64 decoding failed: {0}\")]\n    Base64Decode(#[from] base64::DecodeError),\n    /// Indicates a failure in parsing JSON data.\n    #[error(\"JSON parse error: {0}\")]\n    JsonParse(#[from] serde_json::Error),\n    /// Indicates a failure in building a public key from its representation.\n    #[error(\"Public key build failed: {0}\")]\n    PublicKeyBuild(String),\n    /// Indicates that the token was not signed by the trusted Mojang public key.\n    #[error(\"Token not signed by trusted Mojang key\")]\n    MojangKeyMismatch,\n    /// Indicates that the token's signature is invalid.\n    #[error(\"Invalid signature\")]\n    InvalidSignature,\n    /// Indicates an error related to ECDSA signature operations.\n    #[error(\"ECDSA signature error: {0}\")]","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-auth/src/jwt/mod.rs#L18-L54","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Decode the token header (base64) and confirm it contains an 'x5u' field before verifying","Use tokens issued through the proper Mojang/Xbox authentication chain, which include x5u","If testing locally, construct tokens with an x5u header pointing at (or matching) your public key","Do not strip or rewrite JWT headers in proxies/middleware"],"exampleFix":"// before\nlet header = json!({\"alg\": \"RS256\"}); // no x5u\n// after\nlet header = json!({\"alg\": \"RS256\", \"x5u\": public_key_url});","handlingStrategy":"type-guard","validationCode":"let header_b64 = token.split('.').next().unwrap_or(\"\");\nlet header: serde_json::Value = serde_json::from_slice(&URL_SAFE_NO_PAD.decode(header_b64)?)?;\nif header.get(\"x5u\").is_none() { return Err(\"JWT header missing x5u\"); }","typeGuard":"fn has_x5u(token: &str) -> bool {\n    token.split('.').next()\n        .and_then(|h| base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(h).ok())\n        .and_then(|b| serde_json::from_slice::<serde_json::Value>(&b).ok())\n        .map(|v| v.get(\"x5u\").is_some())\n        .unwrap_or(false)\n}","tryCatchPattern":"match jwt::verify(token) {\n    Err(AuthError::MissingX5U) => { log::warn!(\"token header lacks x5u; non-Mojang issuer?\"); reject_handshake(); }\n    Ok(claims) => { /* proceed */ }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Only accept tokens from the Mojang/Xbox auth chain, which always carries x5u","Decode and inspect JWT headers during development to mirror the expected structure","Never rewrite or strip JWT headers in proxies or middleware"],"tags":["rust","jwt","x5u","authentication","header"],"backgroundTag":"missing-required-argument","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"}