From 8915570a0bfda9f0ff0e34e7fb09bdb9d71580cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Padilla?= <jpadilla@users.noreply.github.com>
Date: Tue, 8 Sep 2026 16:13:35 -0400
Subject: [PATCH] Skip malformed JWKs in JWK sets

---
 jwt/api_jwk.py        |  7 ++++++-
 tests/test_api_jwk.py | 17 +++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/jwt/api_jwk.py b/jwt/api_jwk.py
index 4ae7cc3f5..5ee26b41d 100644
--- a/jwt/api_jwk.py
+++ b/jwt/api_jwk.py
@@ -79,7 +79,12 @@ def __init__(self, jwk_data: JWKDict, algorithm: str | None = None) -> None:
                 f"Unable to find an algorithm for key: {self._jwk_data}",
             ) from None
 
-        self.key = self.Algorithm.from_jwk(self._jwk_data)
+        try:
+            self.key = self.Algorithm.from_jwk(self._jwk_data)
+        except ValueError as error:
+            raise InvalidKeyError(
+                f"Unable to construct key from JWK: {error}"
+            ) from error
 
     @staticmethod
     def from_dict(obj: JWKDict, algorithm: str | None = None) -> PyJWK:
diff --git a/tests/test_api_jwk.py b/tests/test_api_jwk.py
index 221e2e2fa..b081034c0 100644
--- a/tests/test_api_jwk.py
+++ b/tests/test_api_jwk.py
@@ -224,6 +224,23 @@ def test_missing_crypto_library_raises_missing_cryptography_error(self) -> None:
 
 
 class TestPyJWKSet:
+    @crypto_required
+    def test_should_skip_malformed_rsa_key_and_load_remaining_keys(self) -> None:
+        with open(key_path("jwk_rsa_key.json")) as keyfile:
+            malformed_key = json.loads(keyfile.read())
+
+        malformed_key["d"] = "AAAAAA"
+        for parameter in ("p", "q", "dp", "dq", "qi"):
+            del malformed_key[parameter]
+
+        with open(key_path("jwk_rsa_pub.json")) as keyfile:
+            valid_key = json.loads(keyfile.read())
+
+        jwk_set = PyJWKSet.from_dict({"keys": [malformed_key, valid_key]})
+
+        assert len(jwk_set.keys) == 1
+        assert jwk_set.keys[0].key_type == "RSA"
+
     @crypto_required
     def test_should_load_keys_from_jwk_data_dict(self) -> None:
         algo = RSAAlgorithm(RSAAlgorithm.SHA256)
