spring-projects/spring-security · error · HttpMessageNotWritableException
An error occurred writing the OAuth 2.0 Access Token…
Error message
An error occurred writing the OAuth 2.0 Access Token Response: ${ex.getMessage()} What it means
The write-side counterpart of readInternal: writeInternal serializes an OAuth2AccessTokenResponse to JSON via the configured ObjectMapper/jsonMessageConverter and wraps any serialization failure in HttpMessageNotWritableException with the cause's message. This is thrown when the token response object cannot be converted to the target parameterized map/JSON.
Solutions
- Inspect the wrapped cause's message to find the non-serializable/invalid value
- Keep additionalParameters limited to JSON-friendly types (String, Number, Boolean, collections thereof)
- Verify the configured HttpMessageConverter (default MappingJackson2HttpMessageConverter) and ObjectMapper are correctly set up
- When mocking in tests, ensure the converter is registered on the MockMvc message converters
Defensive patterns
Strategy: try-catch
Try / catch
try {
converter.write(tokenResponse, MediaType.APPLICATION_JSON, outputMessage);
} catch (HttpMessageNotWritableException e) {
// inspect e.getCause(); check additionalParameters values are JSON-serializable
} Prevention
- Keep additionalParameters limited to JSON-friendly types
- Validate custom converters/ObjectMapper configuration
- Test token response serialization with MockMvc before deploying
When it happens
Trigger: Server-side token response writing (e.g. a custom token endpoint or test asserting token responses) where accessTokenResponseParametersConverter output or JSON writing fails — e.g. non-serializable values placed in additionalParameters or a misconfigured HttpMessageConverter.
Common situations: Custom token endpoints returning OAuth2AccessTokenResponse with unusual additionalParameters; tests using MockMvc with the converter and a broken message converter setup; ObjectMapper unable to handle a value type.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- An error occurred reading the OAuth 2.0 Access Token…
- An error occurred reading the OAuth 2.0 Device…
- An error occurred reading the OAuth 2.0 Error
- An error occurred writing the OAuth 2.0 Device…
- An error occurred writing the OAuth 2.0 Error
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/ccc2fdf3a5b40363.
Report an issue: GitHub.
Appendix: source
Thrown at oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/http/converter/OAuth2AccessTokenResponseHttpMessageConverter.java:99
}
catch (Exception ex) {
throw new HttpMessageNotReadableException(
"An error occurred reading the OAuth 2.0 Access Token Response: " + ex.getMessage(), ex,
inputMessage);
}
}
@Override
protected void writeInternal(OAuth2AccessTokenResponse tokenResponse, HttpOutputMessage outputMessage)
throws HttpMessageNotWritableException {
try {
Map<String, Object> tokenResponseParameters = this.accessTokenResponseParametersConverter
.convert(tokenResponse);
this.jsonMessageConverter.write(tokenResponseParameters, STRING_OBJECT_MAP.getType(),
MediaType.APPLICATION_JSON, outputMessage);
}
catch (Exception ex) {
throw new HttpMessageNotWritableException(
"An error occurred writing the OAuth 2.0 Access Token Response: " + ex.getMessage(), ex);
}
}
/**
* Sets the {@link Converter} used for converting the OAuth 2.0 Access Token Response
* parameters to an {@link OAuth2AccessTokenResponse}.
* @param accessTokenResponseConverter the {@link Converter} used for converting to an
* {@link OAuth2AccessTokenResponse}
* @since 5.6
*/
public final void setAccessTokenResponseConverter(
Converter<Map<String, Object>, OAuth2AccessTokenResponse> accessTokenResponseConverter) {
Assert.notNull(accessTokenResponseConverter, "accessTokenResponseConverter cannot be null");
this.accessTokenResponseConverter = accessTokenResponseConverter;
}
/**View on GitHub (pinned to 96852e8860)