spring-projects/spring-security · error · OAuth2AuthenticationException
invalid_client_metadata
invalid_client_metadata
Error message
Invalid Client Registration: jwks_uri
What it means
During strict OIDC Dynamic Client Registration, the jwks_uri client metadata field must use the https protocol. If a jwks_uri is provided with a non-https scheme (e.g. http://), validateJwkSetUri throws invalid_client_metadata naming jwks_uri.
Source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationValidator.java:267
catch (URISyntaxException ex) {
throw createException(errorCode, fieldName);
}
}
}
private static void validateJwkSetUri(OidcClientRegistrationAuthenticationContext authenticationContext) {
OidcClientRegistrationAuthenticationToken clientRegistrationAuthentication = authenticationContext
.getAuthentication();
Assert.notNull(clientRegistrationAuthentication.getClientRegistration(), "clientRegistration cannot be null");
URL jwkSetUrl = clientRegistrationAuthentication.getClientRegistration().getJwkSetUrl();
if (jwkSetUrl == null) {
return;
}
if (!"https".equalsIgnoreCase(jwkSetUrl.getProtocol())) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(LogMessage.format("Invalid request: jwks_uri does not use https ('%s')", jwkSetUrl));
}
throw createException("invalid_client_metadata", OidcClientMetadataClaimNames.JWKS_URI);
}
}
private static void validateJwkSetUriSimple(OidcClientRegistrationAuthenticationContext authenticationContext) {
// No validation. Preserves prior behavior.
}
private static void validateScope(OidcClientRegistrationAuthenticationContext authenticationContext) {
OidcClientRegistrationAuthenticationToken clientRegistrationAuthentication = authenticationContext
.getAuthentication();
Assert.notNull(clientRegistrationAuthentication.getClientRegistration(), "clientRegistration cannot be null");
List<String> scopes = clientRegistrationAuthentication.getClientRegistration().getScopes();
if (!CollectionUtils.isEmpty(scopes)) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(LogMessage.format(
"Invalid request: scope must not be set during Dynamic Client Registration ('%s')", scopes));
}
throw createException(OAuth2ErrorCodes.INVALID_SCOPE, OidcClientMetadataClaimNames.SCOPE);View on GitHub (pinned to 96852e8860)
Solutions
- Serve the client's JWK Set over https and register that https URL as jwks_uri
- If the client has no remote JWK Set, omit jwks_uri and supply jwks (inline key set) instead if supported
- Check debug logs for the logged offending jwks_uri value
Example fix
// before
{"jwks_uri": "http://keys.client.example.com/jwks"}
// after
{"jwks_uri": "https://keys.client.example.com/jwks"} Defensive patterns
Strategy: validation
Validate before calling
if (jwksUri != null && !jwksUri.toLowerCase().startsWith("https://")) {
throw new IllegalArgumentException("jwks_uri must be https: " + jwksUri);
} Prevention
- Serve JWK Sets over https only
- Omit jwks_uri entirely when the client has no remote key set
- Check scheme case-insensitively when building client metadata programmatically
When it happens
Trigger: Registering/updating a client via the OIDC client registration endpoint with metadata containing a jwks_uri whose URL protocol is not https while a JWK Set URI is present.
Common situations: Pointing jwks_uri at a local http key server in dev; internal key endpoints exposed over plain http; copying an http URL from legacy infrastructure.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- missing_signature_verifier
- server_error
- Invalid Client Registration: + fieldName
- Invalid Client Registration: + fieldName
- invalid_client_metadata
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/302d30fee06c45ec.
Report an issue: GitHub.