alibaba/nacos · error · IOException
Failed to fetch JWKS, status:
Error message
Failed to fetch JWKS, status:
What it means
Thrown when the JWKS HTTP GET returned a non-200 status. The status code is appended. Nacos built the JWKS URL from discovery but the endpoint rejected or failed the request.
Source
Thrown at plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/token/JwksProvider.java:114
*/
public JWKSet refreshJwkSet() throws IOException {
jwksCache.invalidateAll();
return getJwkSet();
}
private JWKSet fetchJwkSet() throws IOException {
String jwksUri = metadataProvider.getMetadata().getJwksUri();
if (StringUtils.isBlank(jwksUri)) {
throw new IOException("JWKS URI is not configured or discovered");
}
LOGGER.info("Fetching JWKS from: {}", jwksUri);
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(jwksUri))
.header("Accept", "application/json").GET().build();
try {
HttpResponse<String> response =
httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != OidcProtocolConstants.HTTP_STATUS_OK) {
throw new IOException("Failed to fetch JWKS, status: " + response.statusCode());
}
JWKSet result = JWKSet.parse(response.body());
LOGGER.info("Successfully fetched JWKS with {} keys", result.getKeys().size());
return result;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("JWKS fetch interrupted", e);
} catch (ParseException e) {
throw new IOException("Failed to parse JWKS", e);
}
}
/**
* Clear the cached JWK set.
*/
public void clearCache() {
jwksCache.invalidateAll();
}View on GitHub (pinned to 9b989acdf1)
Solutions
- curl the jwks_uri from the discovery doc and read the appended status code.
- For 404: the jwks_uri in discovery is incorrect — fix the IdP discovery configuration.
- For 401/403: ensure the JWKS endpoint is public per OIDC spec.
- For 5xx: check IdP health and retry; the cache TTL (jwks-cache-ttl-seconds) means failures retry on next validation after expiry.
- Verify outbound HTTPS connectivity from the Nacos host to the JWKS URL.
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: probe the JWKS endpoint status before relying on key fetch // (curl the jwks_uri and assert HTTP 200)
Try / catch
try {
jwksProvider.getJwkSet();
} catch (IOException e) {
if (e.getMessage().contains("status:")) {
// transient IdP issue — the Caffeine cache will retry on next miss after TTL
log.warn("JWKS fetch non-200; will retry: {}", e.getMessage());
jwksProvider.refreshJwkSet();
} else {
throw e;
}
} Prevention
- curl the jwks_uri to confirm it returns 200 with a JWK Set.
- Ensure the JWKS endpoint is public per OIDC spec (no auth required).
- Keep jwks-cache-ttl-seconds reasonable so transient failures self-heal.
When it happens
Trigger: JwksProvider.getJwkSet() fetches <jwks_uri> and receives 404, 401/403, 500, etc. Occurs during JWT validation when the cache is cold or expired.
Common situations: jwks_uri from discovery is wrong/stale; JWKS endpoint requires authentication (non-standard); IdP down; key-rotation endpoint temporarily unavailable; corporate proxy blocking the JWKS host.
Related errors
- Token exchange failed:
- Failed to discover OIDC configuration, status:
- JWKS fetch interrupted
- Failed to parse JWKS
- Failed to initialize JWT processor:
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/4bae904febe6715b.
Report an issue: GitHub.