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

  1. Inspect the wrapped cause's message to find the non-serializable/invalid value
  2. Keep additionalParameters limited to JSON-friendly types (String, Number, Boolean, collections thereof)
  3. Verify the configured HttpMessageConverter (default MappingJackson2HttpMessageConverter) and ObjectMapper are correctly set up
  4. 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

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


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)