{"record":{"id":"e796ef6b1c60e423","repo":"jwtk/jjwt","slug":"jwk-set-keys-collection-cannot-be-empty","errorCode":null,"errorMessage":"JWK Set keys collection cannot be empty.","messagePattern":"JWK Set keys collection cannot be empty\\.","errorType":"validation","errorClass":"io.jsonwebtoken.security.MalformedKeySetException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/JwkSetConverter.java","lineNumber":102,"sourceCode":"        // no need for builder parameter type conversion overhead if this isn't present:\n        if (Collections.isEmpty(m) || !m.containsKey(PARAM.getId())) {\n            String msg = \"Missing required \" + PARAM + \" parameter.\";\n            throw new MalformedKeySetException(msg);\n        }\n        Object val = m.get(PARAM.getId());\n        if (val == null) {\n            String msg = \"JWK Set \" + PARAM + \" value cannot be null.\";\n            throw new MalformedKeySetException(msg);\n        }\n        if (!(val instanceof Collection)) {\n            String msg = \"JWK Set \" + PARAM + \" value must be a Collection (JSON Array). Type found: \" +\n                    val.getClass().getName();\n            throw new MalformedKeySetException(msg);\n        }\n        int size = Collections.size((Collection<?>) val);\n        if (size == 0) {\n            String msg = \"JWK Set \" + PARAM + \" collection cannot be empty.\";\n            throw new MalformedKeySetException(msg);\n        }\n\n        // Copy values so we don't mutate the original input\n        Map<String, Object> src = new LinkedHashMap<>(Collections.size((Map<?, ?>) o));\n        for (Map.Entry<?, ?> entry : ((Map<?, ?>) o).entrySet()) {\n            Object key = Assert.notNull(entry.getKey(), \"JWK Set map key cannot be null.\");\n            if (!(key instanceof String)) {\n                String msg = \"JWK Set map keys must be Strings. Encountered key '\" + key + \"' of type \" +\n                        key.getClass().getName();\n                throw new IllegalArgumentException(msg);\n            }\n            String skey = (String) key;\n            src.put(skey, entry.getValue());\n        }\n\n        Set<Jwk<?>> jwks = new LinkedHashSet<>(size);\n        int i = 0; // keep track of which element fails (if any)\n        for (Object candidate : ((Collection<?>) val)) {","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/JwkSetConverter.java#L84-L120","documentation":"Thrown by JwkSetConverter.applyFrom when the JWK Set's keys member is an empty collection. A JWK Set must contain at least one key to be usable, so an empty keys array is rejected as a malformed JWK Set (MalformedKeySetException).","triggerScenarios":"Parsing {\"keys\":[]} or building a JWK Set with an empty collection.","commonSituations":"IdP JWKS endpoint returning an empty array during outages or before keys are provisioned; key rotation removing all keys; misconfigured issuer URL returning a valid-but-empty document.","solutions":["Ensure the JWKS source contains at least one key","Check the issuer/JWKS endpoint for provisioning or outage issues","Treat empty keys as retryable/re-fetchable upstream (cache refresh) and surface a clear error to users"],"exampleFix":"// before\n{\"keys\":[]}\n// after\n{\"keys\":[{\"kty\":\"RSA\",\"n\":\"...\",\"e\":\"AQAB\",\"kid\":\"key-1\",\"alg\":\"RS256\"}]}","handlingStrategy":"validation","validationCode":"Collection<?> keys = (Collection<?>) m.get(\"keys\"); if (keys == null || keys.isEmpty()) { throw new IllegalArgumentException(\"JWKS must contain at least one key\"); }","typeGuard":"boolean hasAtLeastOneKey(Map<?,?> m) { Object k = m == null ? null : m.get(\"keys\"); return k instanceof Collection<?> c && !c.isEmpty(); }","tryCatchPattern":"try { jwkSet = Jwks.setParser().build().parse(json); } catch (MalformedKeySetException e) { scheduleJwksRefresh(); log.warn(\"Empty JWKS from upstream: {}\", e.getMessage()); }","preventionTips":["Monitor upstream JWKS endpoints for empty responses","Cache last-known-good keys and re-fetch on empty results","Confirm issuer URL/key provisioning before deployment"],"tags":["jwt","jwks","validation","empty-value"],"backgroundTag":"empty-required-field","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}