alibaba/nacos · error · IOException

Failed to parse JWKS

Error message

Failed to parse JWKS

What it means

Thrown when JWKSet.parse(body) fails because the JWKS endpoint response is not a valid JWK Set document. The ParseException is wrapped. This means the HTTP call succeeded (200) but the body is not parseable as a JSON Web Key Set.

Source

Thrown at plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/token/JwksProvider.java:123

            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

  1. Inspect the wrapped ParseException cause for the exact parse failure.
  2. curl the jwks_uri and confirm the body is a JSON object with a 'keys' array of JWKs.
  3. Correct jwks_uri in the IdP discovery if it points to the wrong endpoint.
  4. Ensure no proxy returns an HTML/JSON error page with a 200 status at the JWKS URL.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: confirm the JWKS body is a JSON object with a 'keys' array
// (curl jwks_uri and assert body contains "keys":[)

Try / catch

try {
    jwksProvider.getJwkSet();
} catch (IOException e) {
    if ("Failed to parse JWKS".equals(e.getMessage())) {
        Throwable cause = e.getCause(); // ParseException
        log.error("JWKS body unparseable: {}", cause == null ? "?" : cause.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: JWKS endpoint returns 200 but the body is malformed JSON, an HTML page, a JSON object that isn't a JWK Set (missing 'keys' array), or empty.

Common situations: jwks_uri points to a non-JWKS endpoint returning 200 (e.g. a UI page); IdP returns a JSON error object instead of a key set; proxy injecting non-JSON content; partial/truncated JWKS body.

Understand the failure class

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/d7808ba04ca3a144. Report an issue: GitHub.