Skip to content
ecdsa.com
PyJWT (Python)JWT libraries

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

How to fix it

  1. 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. 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")

Related errors

Browse the full signature error database