spring-projects/spring-security · error · IllegalStateException

Failed to select the JWK(s) -> ${ex.getMessage()}

Error message

Failed to select the JWK(s) -> ${ex.getMessage()}

What it means

This IllegalStateException from NimbusJwkSetEndpointFilter.doFilterInternal is thrown when the JWKSource fails to select JWKs for the JWK Set endpoint request. The original exception message is appended so the underlying key-loading failure is visible. Without a JWK Set, clients cannot discover the server's public keys.

Source

Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/NimbusJwkSetEndpointFilter.java:98

		this.jwkSelector = new JWKSelector(new JWKMatcher.Builder().build());
		this.requestMatcher = PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, jwkSetEndpointUri);
	}

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		if (!this.requestMatcher.matches(request)) {
			filterChain.doFilter(request, response);
			return;
		}

		JWKSet jwkSet;
		try {
			jwkSet = new JWKSet(this.jwkSource.get(this.jwkSelector, null));
		}
		catch (Exception ex) {
			throw new IllegalStateException("Failed to select the JWK(s) -> " + ex.getMessage(), ex);
		}

		response.setContentType(MediaType.APPLICATION_JSON_VALUE);
		try (Writer writer = response.getWriter()) {
			writer.write(jwkSet.toString()); // toString() excludes private keys
		}
	}

}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Read the wrapped message to find why JWKSource.get() failed
  2. Verify the key store/PEM file exists, is readable, and the password is correct
  3. Ensure JWKSource is properly initialized with at least one key before serving requests
  4. Re-test the /oauth2/jwks endpoint after fixing key loading

Example fix

// before: missing keystore at runtime
JWKSource<SecurityContext> jwkSource = new JWKSetSource(new File("/wrong/path/keystore.p12"));
// after: verify and fail fast at startup
if (!Files.exists(Path.of("/etc/certs/keystore.p12"))) {
    throw new IllegalStateException("Keystore missing");
}
JWKSource<SecurityContext> jwkSource = loadJwks("/etc/certs/keystore.p12");
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast at startup if keys cannot be loaded
List<JWK> keys = jwkSource.get(new JWKSelector(new JWKMatcher.Builder().build()), null);
if (keys == null || keys.isEmpty()) throw new IllegalStateException("No JWKs loaded");

Type guard

boolean hasLoadableJwks(JWKSource<SecurityContext> src) {
    try { return !src.get(new JWKSelector(new JWKMatcher.Builder().build()), null).isEmpty(); }
    catch (Exception e) { return false; }
}

Try / catch

try {
    mockMvc.perform(get("/oauth2/jwks"));
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Failed to select the JWK(s)")) {
        logger.error("JWK source failure: {}", e.getCause());
    }
}

Prevention

When it happens

Trigger: A GET to the JWK Set endpoint (default /oauth2/jwks) while JWKSource.get() throws — e.g. key store unavailable, decryption failure, or selector matching failure.

Common situations: Keystore/PEM file missing or unreadable at runtime; wrong keystore password; keys not loaded at startup; misconfigured JWKSet bean after rotation.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/3723021a15b615e4. Report an issue: GitHub.