spring-projects/spring-security · error · HttpMessageNotReadableException
An error occurred reading the OAuth 2.0 Device Authorization
Error message
An error occurred reading the OAuth 2.0 Device Authorization Response: ${ex.getMessage()} What it means
This HttpMessageNotReadableException is thrown by OAuth2DeviceAuthorizationResponseHttpMessageConverter.readInternal when the JSON device authorization response from the authorization server cannot be converted into an OAuth2DeviceAuthorizationResponse. It wraps any exception (parse error, missing required parameters like device_code or verification_uri, type mismatches) produced by the JSON message converter or the parameter converter. The original cause message is appended for diagnosis.
Source
Thrown at oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/http/converter/OAuth2DeviceAuthorizationResponseHttpMessageConverter.java:89
}
@Override
protected boolean supports(Class<?> clazz) {
return OAuth2DeviceAuthorizationResponse.class.isAssignableFrom(clazz);
}
@Override
@SuppressWarnings("unchecked")
protected OAuth2DeviceAuthorizationResponse readInternal(Class<? extends OAuth2DeviceAuthorizationResponse> clazz,
HttpInputMessage inputMessage) throws HttpMessageNotReadableException {
try {
Map<String, Object> deviceAuthorizationResponseParameters = (Map<String, Object>) this.jsonMessageConverter
.read(STRING_OBJECT_MAP.getType(), null, inputMessage);
return this.deviceAuthorizationResponseConverter.convert(deviceAuthorizationResponseParameters);
}
catch (Exception ex) {
throw new HttpMessageNotReadableException(
"An error occurred reading the OAuth 2.0 Device Authorization Response: " + ex.getMessage(), ex,
inputMessage);
}
}
@Override
protected void writeInternal(OAuth2DeviceAuthorizationResponse deviceAuthorizationResponse,
HttpOutputMessage outputMessage) throws HttpMessageNotWritableException {
try {
Map<String, Object> deviceAuthorizationResponseParameters = this.deviceAuthorizationResponseParametersConverter
.convert(deviceAuthorizationResponse);
this.jsonMessageConverter.write(deviceAuthorizationResponseParameters, STRING_OBJECT_MAP.getType(),
MediaType.APPLICATION_JSON, outputMessage);
}
catch (Exception ex) {
throw new HttpMessageNotWritableException(
"An error occurred writing the OAuth 2.0 Device Authorization Response: " + ex.getMessage(), ex);View on GitHub (pinned to 96852e8860)
Solutions
- Log the wrapped cause (ex.getCause()) to see the actual conversion failure.
- Verify the device authorization endpoint URL returns application/json per RFC 8628.
- Check the response contains required parameters: device_code, verification_uri (and expires_in/user_code as configured).
- Inspect for a proxy/gateway rewriting the response body (HTML error pages).
- Set the converter's jsonMessageConverter (MappingJackson2HttpMessageConverter) so Jackson is on the classpath and configured.
Example fix
// before
OAuth2DeviceAuthorizationResponse response = converter.read(OAuth2DeviceAuthorizationResponse.class, inputMessage); // may throw
// after
try {
OAuth2DeviceAuthorizationResponse response = converter.read(OAuth2DeviceAuthorizationResponse.class, inputMessage);
} catch (HttpMessageNotReadableException ex) {
logger.error("Device authorization response read failed", ex.getCause());
throw ex;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!contentTypeCompatible(MediaType.APPLICATION_JSON)) {
throw new IllegalArgumentException("Device authorization response must be JSON");
} Try / catch
try {
OAuth2DeviceAuthorizationResponse r = converter.read(OAuth2DeviceAuthorizationResponse.class, inputMessage);
} catch (HttpMessageNotReadableException ex) {
logger.error("Device auth response unreadable", ex.getCause());
throw new OAuth2AuthorizationException(new OAuth2Error("invalid_device_authorization_response", ex.getMessage(), null), ex);
} Prevention
- Assert the device authorization endpoint returns application/json before wiring it in.
- Check required parameters (device_code, verification_uri) are present in a response contract test.
- Keep Jackson on the classpath for the converter.
- Watch for proxies returning HTML error pages in staging environments.
When it happens
Trigger: Calling readInternal/read on an OAuth2DeviceAuthorizationResponseHttpMessageConverter with a response body that is not valid JSON, is not a JSON object, or lacks required parameters (device_code, verification_uri) that OAuth2DeviceAuthorizationResponseParametersConverter requires.
Common situations: The device authorization endpoint returns an HTML error page instead of JSON (proxy, wrong URL), returns an error payload with HTTP 400 (e.g. authorization_pending is misused on this endpoint), or a custom message converter produces unexpected types.
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 Device Authorization
- An error occurred reading the OAuth 2.0 Error: ${ex.getMessa
- An error occurred writing the OAuth 2.0 Error: ${ex.getMessa
- invalid_token_response
- Unable to create an {OAuth2AuthorizedClientManager} bean. Ex
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/26d91add59db8ea3.
Report an issue: GitHub.