Error message
Invalid crypto padding
Also printed as
- Invalid header padding
- Invalid payload padding
- jwt.exceptions.DecodeError: Invalid crypto padding
The word before "padding" names the segment: `header`, `payload` or `crypto` (the signature).
PyJWT (Python) — jwt.exceptions.DecodeError while base64url-decoding a segment
What it means
PyJWT split the token into three segments but could not base64url-decode one of them. "crypto padding" refers to the third (signature) segment, "header padding" and "payload padding" to the first and second. JWS segments must use the URL-safe base64 alphabet (`A–Z a–z 0–9 - _`) without `=` padding; spaces, `+`, `/` or a wrong length make decoding fail before any signature check.
Why it happens
The Bearer prefix is still attached
commonPassing `"Bearer eyJ…"` puts a space and the word Bearer into the header segment, which then fails with "Invalid header padding".
A producer used standard base64
commonHand-written signers that use `base64.b64encode` instead of the URL-safe variant, or that keep the `=` padding, produce segments with `+`, `/` or `=`. Most often this hits the signature segment, giving "Invalid crypto padding".
The token was URL-encoded or decoded on the way
occasionalTokens passed in query strings or form fields can arrive with `%2B`/`%3D` sequences or with `+` turned into a space by a form decoder.
Characters were added or lost in a copy
occasionalLine breaks from a terminal, quotes from JSON, or an ellipsis inserted by a log viewer change the segment lengths and alphabet.
How to fix it
- 1.
Strip the scheme and validate the alphabet
Accept only `Bearer <token>` where the token matches the base64url JWS pattern; answer 401 for everything else before calling PyJWT.
python import re BASE64URL_JWS = re.compile(r"^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$") def extract(authorization: str) -> str: scheme, _, token = authorization.partition(" ") token = token.strip() if scheme.lower() != "bearer" or not BASE64URL_JWS.match(token): raise ValueError("not a compact JWS") return token - 2.
Encode with base64url and no padding
If you build tokens yourself, use URL-safe base64 and remove trailing `=`. Better: let a JOSE library assemble the token.
python import base64 def b64url(data: bytes) -> str: # JWS uses base64url WITHOUT padding (RFC 7515 section 2). return base64.urlsafe_b64encode(data).rstrip(b"=").decode("ascii")