Pumpkin-MC/Pumpkin · error · AuthError
Invalid token format
Error message
Invalid token format
What it means
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.
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
Example fix
// before
verify(token)?; // panics/errors when token is malformed
// after
let parts: Vec<&str> = token.split('.').collect();
if parts.len() != 3 { return Err(AuthError::InvalidTokenFormat); }
verify(token)?; Defensive patterns
Strategy: validation
Validate before calling
let parts: Vec<&str> = token.split('.').collect();
if parts.len() != 3 || parts.iter().any(|p| p.is_empty()) { return Err("token must have 3 non-empty JWT segments"); } Type guard
fn is_jwt_shaped(token: &str) -> bool {
let parts: Vec<&str> = token.split('.').collect();
parts.len() == 3 && parts.iter().all(|p| !p.is_empty())
} Try / catch
match jwt::verify(token) {
Err(AuthError::InvalidTokenFormat) => { log::warn!("client sent malformed token"); reject_handshake(); }
Ok(claims) => { /* proceed */ }
Err(e) => return Err(e.into()),
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- x5u not found in header
- JSON parse error
- Public key build failed
- Token not signed by trusted Mojang key
- Invalid signature
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/f700b2a5dbfca8d6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-auth/src/jwt/mod.rs:33
/// Represents the claims extracted from a Minecraft Bedrock player's JWT token.
///
/// 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")]View on GitHub (pinned to 8d4639e25a)