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

  1. Ensure token segments use base64url (URL_SAFE) decoding, not standard base64, on both ends
  2. Inspect the raw token for URL-encoded characters (%3D, %2B), whitespace, or line breaks and clean them
  3. Verify the token isn't truncated by transport (headers size limits, database column length)
  4. 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

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)