{"record":{"id":"b99e1fd0f0b53b18","repo":"spring-projects/spring-security","slug":"an-error-occurred-while-attempting-to-decode-the-j-b99e1f","errorCode":null,"errorMessage":"An error occurred while attempting to decode the Jwt: Malformed Jwk set","messagePattern":"An error occurred while attempting to decode the Jwt: Malformed Jwk set","errorType":"exception","errorClass":"JwtException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusJwtDecoder.java","lineNumber":178,"sourceCode":"\t}\n\n\tprivate Jwt createJwt(String token, JWT parsedJwt) {\n\t\ttry {\n\t\t\t// Verify the signature\n\t\t\tJWTClaimsSet jwtClaimsSet = this.jwtProcessor.process(parsedJwt, null);\n\t\t\tMap<String, Object> headers = new LinkedHashMap<>(parsedJwt.getHeader().toJSONObject());\n\t\t\tMap<String, Object> claims = this.claimSetConverter.convert(jwtClaimsSet.getClaims());\n\t\t\t// @formatter:off\n\t\t\treturn Jwt.withTokenValue(token)\n\t\t\t\t\t.headers((h) -> h.putAll(headers))\n\t\t\t\t\t.claims((c) -> c.putAll(claims))\n\t\t\t\t\t.build();\n\t\t\t// @formatter:on\n\t\t}\n\t\tcatch (RemoteKeySourceException ex) {\n\t\t\tthis.logger.trace(\"Failed to retrieve JWK set\", ex);\n\t\t\tif (ex.getCause() instanceof ParseException) {\n\t\t\t\tthrow new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, \"Malformed Jwk set\"), ex);\n\t\t\t}\n\t\t\tthrow new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);\n\t\t}\n\t\tcatch (JOSEException ex) {\n\t\t\tthis.logger.trace(\"Failed to process JWT\", ex);\n\t\t\tthrow new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tthis.logger.trace(\"Failed to process JWT\", ex);\n\t\t\tif (ex.getCause() instanceof ParseException) {\n\t\t\t\tthrow new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, \"Malformed payload\"), ex);\n\t\t\t}\n\t\t\tthrow new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);\n\t\t}\n\t}\n\n\tprivate Jwt validateJwt(Jwt jwt) {\n\t\tOAuth2TokenValidatorResult result = this.jwtValidator.validate(jwt);","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusJwtDecoder.java#L160-L196","documentation":"createJwt wraps RemoteKeySourceException from the JWK source: when the failure cause is a ParseException, the JWK Set document fetched from the jwk-set-uri was not valid JSON, so it throws JwtException 'An error occurred while attempting to decode the Jwt: Malformed Jwk set'.","triggerScenarios":"decode() → createJwt → JWKSet retrieval (RemoteJWKSet) fetches the JWKS endpoint and parsing the response body as JSON throws ParseException, wrapped in RemoteKeySourceException with ParseException as cause.","commonSituations":"jwk-set-uri pointing at an HTML error page, login page, or wrong endpoint; a proxy/gateway returning an HTML 200 error page; misconfigured mock server returning non-JSON; cached/stale JWK responses corrupted by intermediary.","solutions":["curl the configured jwk-set-uri and confirm the body is valid JSON containing a 'keys' array.","Fix the jwk-set-uri (e.g. use the provider's /.well-known/openid-configuration jwks_uri value) instead of guessing the URL.","Check proxies/gateways are not interposing HTML content (auth redirects, error pages) on the JWKS request.","Clear any cached JWKS (restart or adjust cache settings) if a previously bad response was cached."],"exampleFix":"// before\nNimbusJwtDecoder.withJwkSetUri(\"https://auth.example.com/certs\") // wrong path returning HTML\n// after\nNimbusJwtDecoder.withJwkSetUri(\"https://auth.example.com/oauth2/default/jwks\") // real JWKS endpoint","handlingStrategy":"try-catch","validationCode":"// preflight: JWKS endpoint must return JSON\n// curl -fsS \"$JWK_SET_URI\" | python3 -c 'import json,sys; json.load(sys.stdin); print(\"valid json\")'","typeGuard":null,"tryCatchPattern":"try { return jwtDecoder.decode(token); }\ncatch (JwtException e) {\n    if (e.getMessage().contains(\"Malformed Jwk set\")) {\n        // JWKS endpoint returned non-JSON: fix jwk-set-uri or proxy, then retry after cache expiry\n    }\n}","preventionTips":["Take jwks_uri from the provider's discovery document rather than guessing the path","Verify the JWKS URL from the app host (auth redirects and HTML error pages are common culprits)","Monitor the JWKS endpoint in health checks; keep JWK cache TTL sane so bad responses expire"],"tags":["jwks","jwt","http","json"],"backgroundTag":"invalid-json-response","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}