{"record":{"id":"4f4850098e8a7f46","repo":"alibaba/nacos","slug":"jwks-fetch-interrupted","errorCode":null,"errorMessage":"JWKS fetch interrupted","messagePattern":"JWKS fetch interrupted","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"warning","filePath":"plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/token/JwksProvider.java","lineNumber":121,"sourceCode":"        String jwksUri = metadataProvider.getMetadata().getJwksUri();\n        if (StringUtils.isBlank(jwksUri)) {\n            throw new IOException(\"JWKS URI is not configured or discovered\");\n        }\n        LOGGER.info(\"Fetching JWKS from: {}\", jwksUri);\n        HttpRequest request = HttpRequest.newBuilder().uri(URI.create(jwksUri))\n            .header(\"Accept\", \"application/json\").GET().build();\n        try {\n            HttpResponse<String> response =\n                httpClient.send(request, HttpResponse.BodyHandlers.ofString());\n            if (response.statusCode() != OidcProtocolConstants.HTTP_STATUS_OK) {\n                throw new IOException(\"Failed to fetch JWKS, status: \" + response.statusCode());\n            }\n            JWKSet result = JWKSet.parse(response.body());\n            LOGGER.info(\"Successfully fetched JWKS with {} keys\", result.getKeys().size());\n            return result;\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new IOException(\"JWKS fetch interrupted\", e);\n        } catch (ParseException e) {\n            throw new IOException(\"Failed to parse JWKS\", e);\n        }\n    }\n    \n    /**\n     * Clear the cached JWK set.\n     */\n    public void clearCache() {\n        jwksCache.invalidateAll();\n    }\n}\n","sourceCodeStart":103,"sourceCodeEnd":134,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/token/JwksProvider.java#L103-L134","documentation":"Thrown when the thread was interrupted during the blocking JWKS HTTP fetch (httpClient.send). The interrupt flag is re-set before throwing. This is a thread-lifecycle condition, not a request-logic error.","triggerScenarios":"The thread performing JWKS fetch is interrupted while httpClient.send blocks — during shutdown, forced pool termination, or an interrupt during a slow JWKS response.","commonSituations":"Server shutting down during token validation; thread pool interrupted; slow IdP JWKS endpoint combined with an aggressive interrupt.","solutions":["Treat as transient: the next validation retries the fetch once the cache is empty.","If recurring at runtime, check for code interrupting validation threads.","Ensure the JWKS endpoint responds promptly to avoid prolonged blocking.","On shutdown this is benign and can be ignored."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    jwksProvider.getJwkSet();\n} catch (IOException e) {\n    if (\"JWKS fetch interrupted\".equals(e.getMessage())) {\n        // transient thread interruption — retry once if the thread is no longer interrupted\n        if (!Thread.currentThread().isInterrupted()) {\n            jwksProvider.getJwkSet();\n        }\n    } else {\n        throw e;\n    }\n}","preventionTips":["Do not interrupt threads performing JWKS fetch unless shutting down.","Treat interrupted fetch as transient; the cache retries on next validation.","Suppress and log during shutdown."],"tags":["oidc","network","threading","jwks"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}