spring-projects/spring-security · error · HttpMessageNotReadableException
An error occurred reading the OAuth 2.0 Client Registration:
Error message
An error occurred reading the OAuth 2.0 Client Registration: + ex.getMessage()
What it means
OAuth2ClientRegistrationHttpMessageConverter.readInternal wraps any exception raised while reading the request/response body as JSON and converting it to an OAuth2ClientRegistration. The JSON converter parses the Map<String,Object> and clientRegistrationConverter.convert() maps it to the typed object; any failure (malformed JSON, missing/invalid registration fields) is rethrown as org.springframework.http.converter.HttpMessageNotReadableException with the cause attached. This means the client registration document could not be read or validated.
Source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/http/converter/OAuth2ClientRegistrationHttpMessageConverter.java:93
this.jsonMessageConverter = converter;
}
@Override
protected boolean supports(Class<?> clazz) {
return OAuth2ClientRegistration.class.isAssignableFrom(clazz);
}
@Override
@SuppressWarnings("unchecked")
protected OAuth2ClientRegistration readInternal(Class<? extends OAuth2ClientRegistration> clazz,
HttpInputMessage inputMessage) throws HttpMessageNotReadableException {
try {
Map<String, Object> clientRegistrationParameters = (Map<String, Object>) this.jsonMessageConverter
.read(STRING_OBJECT_MAP.getType(), null, inputMessage);
return this.clientRegistrationConverter.convert(clientRegistrationParameters);
}
catch (Exception ex) {
throw new HttpMessageNotReadableException(
"An error occurred reading the OAuth 2.0 Client Registration: " + ex.getMessage(), ex,
inputMessage);
}
}
@Override
protected void writeInternal(OAuth2ClientRegistration clientRegistration, HttpOutputMessage outputMessage)
throws HttpMessageNotWritableException {
try {
Map<String, Object> clientRegistrationParameters = this.clientRegistrationParametersConverter
.convert(clientRegistration);
this.jsonMessageConverter.write(clientRegistrationParameters, STRING_OBJECT_MAP.getType(),
MediaType.APPLICATION_JSON, outputMessage);
}
catch (Exception ex) {
throw new HttpMessageNotWritableException(
"An error occurred writing the OAuth 2.0 Client Registration: " + ex.getMessage(), ex);
}View on GitHub (pinned to 96852e8860)
Solutions
- Check the cause of the HttpMessageNotReadableException — if it is a JSON parse error the body is malformed; log the raw body to see what was actually returned.
- Verify the response Content-Type is application/json and the endpoint actually returns a JSON registration document, not an HTML error page.
- Validate the registration JSON against the OAuth2 client registration schema (required fields present) before/after conversion.
- Ensure the JSON converter configured via setJsonMessageConverter supports the incoming MediaType.
- Relax or correct a custom Converter registered with setClientRegistrationConverter if it rejects a valid registration.
Example fix
// before
ResponseEntity<String> resp = rest.getForEntity(registrationUri, String.class);
OAuth2ClientRegistration reg = converter.read(OAuth2ClientRegistration.class, new MockClientHttpResponse(resp.getBody(), resp.getHeaders())); // fails on HTML bodies
// after
if (!resp.getHeaders().getContentType().isCompatibleWith(MediaType.APPLICATION_JSON)) {
throw new IllegalStateException("Registration endpoint returned non-JSON: " + resp.getBody());
}
OAuth2ClientRegistration reg = converter.read(OAuth2ClientRegistration.class, new MockClientHttpResponse(resp.getBody(), resp.getHeaders())); Defensive patterns
Strategy: validation
Validate before calling
// before reading
if (body == null || body.isBlank()) throw new OAuth2IntrospectionException("empty registration body");
objectMapper.readTree(body); // throws if malformed JSON
if (!contentType.isCompatibleWith(MediaType.APPLICATION_JSON)) throw new IllegalArgumentException("non-JSON content type"); Try / catch
try {
return converter.read(OAuth2ClientRegistration.class, inputMessage);
} catch (HttpMessageNotReadableException e) {
logger.warn("Invalid client registration response: {}", e.getCause().toString());
throw new OAuth2ClientRegistrationException("Unreadable client registration", e);
} Prevention
- Always check HTTP status and Content-Type before passing a response to the converter.
- Log raw response bodies on failure to diagnose non-JSON error pages.
- Validate registration documents against the OAuth2/OIDC registration schema upstream.
- Pin and test the JSON converter configuration used with the converter.
When it happens
Trigger: Calling OAuth2ClientRegistrationHttpMessageConverter.read() (via readInternal) when the body is not parseable JSON (syntax error, wrong Content-Type), the JSON converter throws, or the clientRegistration Converter.convert() throws because required fields (client_id, authorization/token/revocation endpoints, etc.) are missing or invalid.
Common situations: The authorization server / registration endpoint returns HTML or an empty/error body instead of JSON; Content-Type is not application/json so the JSON converter refuses to read; an OpenID Provider publishes an incomplete or non-conformant registration response (missing registration_client_uri fields); a custom clientRegistrationConverter is too strict about optional fields.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- An error occurred writing the OAuth 2.0 Authorization Server
- An error occurred writing the OAuth 2.0 Client Registration:
- An error occurred reading the Token Introspection Response:
- Unable to create an {OAuth2AuthorizedClientManager} bean. Ex
- invalid_dpop_proof
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/d29cca89257f1373.
Report an issue: GitHub.