Pumpkin-MC/Pumpkin · error · AuthError
Base64 decoding failed
Error message
Base64 decoding failed: {0} What it means
AuthError::Base64Decode, a wrapped base64::DecodeError (via #[from]) thrown when a JWT part (header, payload, or signature) cannot be Base64-decoded. JWT segments use base64url encoding; malformed characters or standard-base64 padding issues cause this error.
Solutions
- Ensure token segments use base64url (URL_SAFE) decoding, not standard base64, on both ends
- Inspect the raw token for URL-encoded characters (%3D, %2B), whitespace, or line breaks and clean them
- Verify the token isn't truncated by transport (headers size limits, database column length)
- Regenerate a fresh token from the login flow to rule out corruption in storage
Example fix
// before base64::engine::general_purpose::STANDARD.decode(part)?; // fails on '-'/'_' // after use base64::Engine; base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(part)?;
Defensive patterns
Strategy: validation
Validate before calling
const B64URL: base64::engine::GeneralPurpose = base64::engine::general_purpose::URL_SAFE_NO_PAD;
for part in token.split('.') {
if B64URL.decode(part).is_err() { return Err("token segment is not valid base64url"); }
} Type guard
fn token_segments_decode(token: &str) -> bool {
use base64::Engine;
token.split('.').all(|p| base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(p).is_ok())
} Try / catch
match jwt::verify(token) {
Err(AuthError::Base64Decode(e)) => { log::warn!("token base64 corrupt: {e}; check transport"); reject_handshake(); }
Ok(claims) => { /* proceed */ }
Err(e) => return Err(e.into()),
} Prevention
- Use URL_SAFE (base64url) decoding for JWT segments, not STANDARD
- Strip URL-encoding and whitespace from tokens received via query params/headers
- Check storage/transport limits (header size, column length) that could truncate tokens
When it happens
Trigger: Verifying a JWT where any dot-separated segment is not valid base64url — wrong alphabet, missing/incorrect padding handling, binary corruption, or passing a plain-text string as a token.
Common situations: Token stored/retrieved through a system that mangles it (URL encoding, line wrapping, JSON escaping); client uses standard base64 instead of base64url; truncation by fixed-size buffers or logs copy-paste.
Related errors
AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09).
Data as JSON: /api/errors/8c3dcc734bf978b5.
Report an issue: GitHub.
Appendix: source
Thrown at crates/pumpkin-auth/src/jwt/mod.rs:39
/// 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}")]
Ecdsa(#[from] ecdsa::Error),
}
View on GitHub (pinned to 8d4639e25a)