{"record":{"id":"f700b2a5dbfca8d6","repo":"Pumpkin-MC/Pumpkin","slug":"invalid-token-format","errorCode":null,"errorMessage":"Invalid token format","messagePattern":"Invalid token format","errorType":"error_code","errorClass":"AuthError","httpStatus":null,"severity":"error","filePath":"crates/pumpkin-auth/src/jwt/mod.rs","lineNumber":33,"sourceCode":"\n/// Represents the claims extracted from a Minecraft Bedrock player's JWT token.\n///\n/// 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\")]","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-auth/src/jwt/mod.rs#L15-L51","documentation":"AuthError::InvalidTokenFormat from the pumpkin-auth JWT module, thrown during JWT verification when the token does not have the expected three dot-separated parts (header.payload.signature). Microsoft/Mojang session JWTs must be split and each part decoded separately.","triggerScenarios":"Calling JWT verification with a token that contains fewer than 3 dot-separated segments — empty string, an OAuth access token passed instead of the identity JWT, or a corrupted/truncated token.","commonSituations":"Client sends the wrong token type (XBL access token vs. XSTS identity JWT); login handshake data truncated; extra whitespace or wrapping in the token field; Mojang protocol changes not handled.","solutions":["Verify the client is sending the Mojang identity JWT (three parts) from the login handshake, not an access token","Split on '.' and check `parts.len() == 3` before verifying","Log the first ~20 chars and part count of the received token to diagnose what the client actually sent","Update the auth protocol handling if the client/server Minecraft versions differ"],"exampleFix":"// before\nverify(token)?; // panics/errors when token is malformed\n// after\nlet parts: Vec<&str> = token.split('.').collect();\nif parts.len() != 3 { return Err(AuthError::InvalidTokenFormat); }\nverify(token)?;","handlingStrategy":"validation","validationCode":"let parts: Vec<&str> = token.split('.').collect();\nif parts.len() != 3 || parts.iter().any(|p| p.is_empty()) { return Err(\"token must have 3 non-empty JWT segments\"); }","typeGuard":"fn is_jwt_shaped(token: &str) -> bool {\n    let parts: Vec<&str> = token.split('.').collect();\n    parts.len() == 3 && parts.iter().all(|p| !p.is_empty())\n}","tryCatchPattern":"match jwt::verify(token) {\n    Err(AuthError::InvalidTokenFormat) => { log::warn!(\"client sent malformed token\"); reject_handshake(); }\n    Ok(claims) => { /* proceed */ }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Check part count == 3 before calling verify","Ensure clients send the Mojang identity JWT from the login chain, not access tokens","Log token shape (segment count/lengths), never the token itself"],"tags":["rust","jwt","authentication","format"],"backgroundTag":"invalid-argument-format","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"}