spring-projects/spring-security · error · HttpMessageNotWritableException
An error occurred writing the OpenID Client Registration: ${
Error message
An error occurred writing the OpenID Client Registration: ${ex.getMessage()} What it means
OidcClientRegistrationHttpMessageConverter.writeInternal serializes an OidcClientRegistration to the HTTP response. If converting the registration to a parameter map or writing it as JSON fails, the exception is wrapped in an HttpMessageNotWritableException with the message "An error occurred writing the OpenID Client Registration: <cause message>". It indicates the server could not render a client registration (typically the registration response) as JSON.
Source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/http/converter/OidcClientRegistrationHttpMessageConverter.java:108
return this.clientRegistrationConverter.convert(clientRegistrationParameters);
}
catch (Exception ex) {
throw new HttpMessageNotReadableException(
"An error occurred reading the OpenID Client Registration: " + ex.getMessage(), ex, inputMessage);
}
}
@Override
protected void writeInternal(OidcClientRegistration 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 OpenID Client Registration: " + ex.getMessage(), ex);
}
}
/**
* Sets the {@link Converter} used for converting the OpenID Client Registration
* parameters to an {@link OidcClientRegistration}.
* @param clientRegistrationConverter the {@link Converter} used for converting to an
* {@link OidcClientRegistration}
*/
public final void setClientRegistrationConverter(
Converter<Map<String, Object>, OidcClientRegistration> clientRegistrationConverter) {
Assert.notNull(clientRegistrationConverter, "clientRegistrationConverter cannot be null");
this.clientRegistrationConverter = clientRegistrationConverter;
}
/**
* Sets the {@link Converter} used for converting the {@link OidcClientRegistration}View on GitHub (pinned to 96852e8860)
Solutions
- Check the nested cause to identify which conversion or serialization step failed.
- Ensure a functioning JSON HttpMessageConverter (e.g. MappingJackson2HttpMessageConverter) is on the classpath and registered on the endpoint.
- Review any custom clientRegistrationParametersConverter registered on OidcClientRegistrationHttpMessageConverter for bugs or incompatibility.
- Verify no earlier filter/interceptor has committed or closed the response output stream before the endpoint writes.
Example fix
// before (custom converter throws on null client_id issued value)
return Map.of("client_id", registration.getClientId(), "redirect_uris", registration.getRedirectUris());
// after (handle absent values and only include set fields)
Map<String, Object> params = new HashMap<>();
params.put("client_id", registration.getClientId());
if (!registration.getRedirectUris().isEmpty()) {
params.put("redirect_uris", registration.getRedirectUris());
}
return params; Defensive patterns
Strategy: try-catch
Validate before calling
boolean canSerialize(OidcClientRegistration reg) {
return reg != null && reg.getClientId() != null;
} Try / catch
try {
converter.write(registration, MediaType.APPLICATION_JSON, outputMessage);
} catch (HttpMessageNotWritableException ex) {
log.error("Failed to write client registration response: {}", ex.getCause() != null ? ex.getCause().getMessage() : ex.getMessage(), ex);
response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value());
} Prevention
- Keep a working JSON message converter (Jackson) on the classpath and registered.
- Test any custom clientRegistrationParametersConverter against real OidcClientRegistration values.
- Ensure filters/interceptors do not commit the response before the endpoint writes.
When it happens
Trigger: The clientRegistrationEndpoint completes registration and writeInternal is invoked, but OidcClientRegistrationToParametersConverter or the underlying JSON message converter throws — e.g. a null/unset converter, a custom converter that throws, or a configured MappingJackson2HttpMessageConverter that cannot serialize a value in the registration.
Common situations: Spring MVC/Spring Security versions where the default JSON converter is unavailable or misconfigured; overriding the converter via HttpMessageConverters with one that rejects the output; a custom converter returning an incompatible map; response stream already committed/closed by a filter.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- An error occurred reading the OpenID Client Registration: ${
- An error occurred reading the OpenID Provider Configuration:
- An error occurred reading the OAuth 2.0 Authorization Server
- server_error
- Invalid Client Registration: + fieldName
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/e9069a1444b245bf.
Report an issue: GitHub.