spring-projects/spring-security · error · IllegalArgumentException
Unable to resolve Configuration with the provided Issuer of
Error message
Unable to resolve Configuration with the provided Issuer of "${issuer}" What it means
ClientRegistrations.getBuilder fetches the OpenID/OAuth2 discovery document (.well-known/openid-configuration and .well-known/oauth-authorization-server) for the issuer and builds a registration from it. When no endpoint responds with a parseable configuration and no per-endpoint errors were collected, it throws this IllegalArgumentException with the issuer in the message.
Solutions
- Verify the issuer URL in a browser/curl: https://issuer/.well-known/openid-configuration should return JSON with authorization_endpoint, token_endpoint, jwks_uri.
- Fix network/TLS reachability (VPN, proxy, truststore) for the discovery host.
- If the provider has no discovery endpoint, construct the ClientRegistration manually with explicit endpoints instead of ClientRegistrations.fromIssuerLocation.
- Check for issuer path issues: discovery is fetched at issuer + '/.well-known/openid-configuration'; trailing slashes or path segments can break the lookup.
Example fix
// before
ClientRegistration reg = ClientRegistrations.fromOidcIssuerLocation("https://idp.internal"); // unreachable
// after
ClientRegistration.withRegistrationId("idp")
.authorizationUri("https://idp.internal/authorize")
.tokenUri("https://idp.internal/token")
.jwkSetUri("https://idp.internal/jwks")
.userInfoUri("https://idp.internal/userinfo")
.build(); Defensive patterns
Strategy: validation
Validate before calling
// before calling ClientRegistrations, verify discovery is reachable
RestTemplate rest = new RestTemplate();
String meta = rest.getForEntity("https://issuer/.well-known/openid-configuration", String.class).getBody();
if (meta == null || !meta.trim().startsWith("{")) throw new IllegalStateException("issuer has no discovery metadata"); Try / catch
try { ClientRegistrations.fromIssuerLocation(issuer); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unable to resolve Configuration")) { /* use manual registration */ } throw e; } Prevention
- Validate issuer reachability at application startup, not first request
- Use exact issuer strings as advertised by the provider
- Keep the discovery path exempt from gateway auth
When it happens
Trigger: fromOidcIssuerLocation(issuer) or fromIssuerLocation(issuer) where every discovery URL fails (404, connection failure, non-JSON body) but no structured errors list was populated, falling through to the final throw.
Common situations: Typo in the issuer URL; issuer behind a firewall/VPN not reachable at build time; provider does not publish discovery metadata; HTTPS certificate issues; non-JSON responses failing silently.
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
- Unable to resolve Configuration with the provided Issuer of
- invalid_user_info_response
- Unable to resolve the Configuration with the provided…
- consent_required
- insufficient_scope
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/2a19c4d113ebc058.
Report an issue: GitHub.
Appendix: source
Thrown at oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrations.java:290
Supplier<ClientRegistration.Builder>... suppliers) {
String errorMessage = "Unable to resolve Configuration with the provided Issuer of \"" + issuer + "\"";
List<String> errors = new ArrayList<>();
for (Supplier<ClientRegistration.Builder> supplier : suppliers) {
try {
return supplier.get();
}
catch (HttpClientErrorException ex) {
if (!ex.getStatusCode().is4xxClientError()) {
throw ex;
}
errors.add(ex.getMessage());
// else try another endpoint
}
catch (IllegalArgumentException | IllegalStateException ex) {
throw ex;
}
catch (RuntimeException ex) {
throw new IllegalArgumentException(errorMessage, ex);
}
}
if (!errors.isEmpty()) {
throw new IllegalArgumentException(errorMessage + ", errors: " + errors);
}
throw new IllegalArgumentException(errorMessage);
}
private static <T> T parseInput(Map<String, Object> body, ThrowingFunction<JSONObject, T, ParseException> parser) {
try {
return parse(body, parser);
}
catch (RuntimeException ex) {
throw new IllegalArgumentException(ex);
}
}
private static <T> T parse(Map<String, Object> body, ThrowingFunction<JSONObject, T, ParseException> parser) {View on GitHub (pinned to 96852e8860)