Error message
The specified alg value is not allowed
Also printed as
- jwt.exceptions.InvalidAlgorithmError: The specified alg value is not allowed
PyJWT (Python) — jwt.exceptions.InvalidAlgorithmError
What it means
The `alg` in the token's header is not in the `algorithms` list you passed to `jwt.decode()`. PyJWT checks this before verifying the signature, because the header is chosen by whoever produced the token and must not decide how it is verified. The token may be correctly signed — just with an algorithm you have not allowed.
Why it happens
The issuer switched algorithms
commonA provider migration from RS256 to ES256 (or adding an EdDSA key) breaks verifiers that pin the old value. Failures begin exactly at the rollout and affect only newly issued tokens.
The JWK fixes a different algorithm
occasionalWhen you pass a `PyJWK` (for example from `PyJWKClient`), its `alg` restricts verification as well. A JWK labelled RS256 cannot verify an ES256 token.
A token from somewhere else
occasionalTokens from another issuer, an internal HS256 token sent to a public API, or a probe with `alg: "none"` or `HS256` against an RSA-protected API. In those cases the rejection is correct.
How to fix it
- 1.
Read the header first
`jwt.get_unverified_header()` shows `alg` and `kid` without trusting anything. Compare it with your allow-list and with the keys your issuer publishes.
python print(jwt.get_unverified_header(token)) # {'alg': 'ES256', 'kid': '...', 'typ': 'JWT'} - 2.
Allow exactly the issuer's algorithm
Put the algorithm your issuer uses in `algorithms`, and resolve keys from its JWKS. During a migration list both algorithms, each matched to its own key by `kid`.
python from jwt import PyJWKClient jwks = PyJWKClient("https://issuer.example.com/.well-known/jwks.json") signing_key = jwks.get_signing_key_from_jwt(token) claims = jwt.decode( token, signing_key.key, algorithms=["ES256"], # the algorithm(s) your issuer actually uses, never the token's own header audience="https://api.example.com", )