---
title: "pyjwt Breaking Changes on PyPI | Since.dev"
description: "What each pyjwt release removed, renamed or changed: 7 breaking changes in 3 versions on PyPI, each with its source."
canonical_url: https://since.dev/packages/pypi/pyjwt
last_updated: 2026-09-23
---

# pyjwt breaking changes

Every breaking API change we have recorded in pyjwt on PyPI: 7 breaking changes in 3 versions. Below are its newest 3 versions, removals and renames first, each with its source.

Newest change September 23, 2026

## 2.15.0

2 breaking changes, first published September 23, 2026.

- **Signature changed** `jwt.jwk_set_cache.JWKSetCache.put`  

Was def put(self, jwk_set: PyJWKSet) -> None; now def put(self, jwk_set: Optional\[Union\[PyJWKSet, dict\[str, Any\]\]\]) -> None. [pypi.org](https://pypi.org/project/PyJWT/2.15.0/)
- **Signature changed** `jwt.PyJWK.from_json`  

Was @staticmethod def from_json(data: str, algorithm: None = None) -> PyJWK; now @staticmethod def from_json(data: str, algorithm: str | None = None) -> PyJWK. [pypi.org](https://pypi.org/project/PyJWT/2.15.0/)

## 2.14.0

1 breaking change, first published September 11, 2026.

- **Signature changed** `jwt.PyJWKClient.__init__`  

Was def \_\_init\_\_(self, uri: str, cache_keys: bool = False, max_cached_keys: int = 16, cache_jwk_set: bool = True, lifespan: float = 300, headers: dict\[str, Any\] | None = None, timeout: float = 30, ssl_context: SSLContext | None = None)... [pypi.org](https://pypi.org/project/PyJWT/2.14.0/)

## 2.13.0

4 breaking changes, first published May 21, 2026.

- **Behavior changed** `HMACAlgorithm.prepare_key`  

Empty HMAC secrets are rejected outright with InvalidKeyError. Applications that passed an empty string or bytes as a secret must configure a real key. [github.com](https://github.com/jpadilla/pyjwt/releases/tag/2.13.0)
- **Behavior changed** `PyJWK`  

Verification now requires the token header alg to equal the PyJWK's algorithm. Tokens relying on a mismatch now fail with InvalidAlgorithmError. [github.com](https://github.com/jpadilla/pyjwt/releases/tag/2.13.0)
- **Behavior changed** `PyJWKClient`  

PyJWKClient now refuses URIs whose scheme is not http or https, including file:// URIs. Tests or dev setups must serve JWKS over HTTP or load keys with PyJWKSet.from_dict. [github.com](https://github.com/jpadilla/pyjwt/releases/tag/2.13.0)
- **Behavior changed** `PyJWT.decode`  

Passing enforce_minimum_key_length in decode options now enforces minimum key size, so undersized keys raise InvalidKeyError. [github.com](https://github.com/jpadilla/pyjwt/releases/tag/2.13.0)

## Check your code

These are the changes. To see which of them reach your code, [scan a public repository](https://since.dev/scan.md), or have your coding agent call `check_code` with your manifest or lockfile over [MCP](https://since.dev/docs.md#mcp). [The API](https://since.dev/docs.md#api) reads every change in every version, not only the newest. On Team and up, a fix pull request opens for the changes that reach a connected repository. Nothing merges or deploys.

## Put your code on continuous management.

Scan a public repository now, or give your agent one line.

### See how out of date your code is.

[Scan a repository](https://since.dev/scan.md). Any public GitHub repository. No sign-in.

### Tell your agent what changed since it was trained.

`claude mcp add --transport http since https://api.since.dev/mcp`

---

Every page on this site as Markdown: https://since.dev/sitemap.md. For agents: https://since.dev/llms.txt.
