spring-projects/spring-security · error · HttpMessageNotWritableException

An error occurred writing the OAuth 2.0 Error: ${ex.getMessa

Error message

An error occurred writing the OAuth 2.0 Error: ${ex.getMessage()}

What it means

This HttpMessageNotWritableException is thrown by OAuth2ErrorHttpMessageConverter.writeInternal when the OAuth2Error cannot be converted to a parameter map and written as JSON. It wraps exceptions from errorParametersConverter.convert or jsonMessageConverter.write.

Source

Thrown at oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/http/converter/OAuth2ErrorHttpMessageConverter.java:101

				.stream()
				.collect(Collectors.toMap(Map.Entry::getKey, (entry) -> String.valueOf(entry.getValue()))));
		}
		catch (Exception ex) {
			throw new HttpMessageNotReadableException(
					"An error occurred reading the OAuth 2.0 Error: " + ex.getMessage(), ex, inputMessage);
		}
	}

	@Override
	protected void writeInternal(OAuth2Error oauth2Error, HttpOutputMessage outputMessage)
			throws HttpMessageNotWritableException {
		try {
			Map<String, String> errorParameters = this.errorParametersConverter.convert(oauth2Error);
			this.jsonMessageConverter.write(errorParameters, STRING_OBJECT_MAP.getType(), MediaType.APPLICATION_JSON,
					outputMessage);
		}
		catch (Exception ex) {
			throw new HttpMessageNotWritableException(
					"An error occurred writing the OAuth 2.0 Error: " + ex.getMessage(), ex);
		}
	}

	/**
	 * Sets the {@link Converter} used for converting the OAuth 2.0 Error parameters to an
	 * {@link OAuth2Error}.
	 * @param errorConverter the {@link Converter} used for converting to an
	 * {@link OAuth2Error}
	 */
	public final void setErrorConverter(Converter<Map<String, String>, OAuth2Error> errorConverter) {
		Assert.notNull(errorConverter, "errorConverter cannot be null");
		this.errorConverter = errorConverter;
	}

	/**
	 * Sets the {@link Converter} used for converting the {@link OAuth2Error} to a
	 * {@code Map} representation of the OAuth 2.0 Error parameters.

View on GitHub (pinned to 96852e8860)

Solutions

  1. Check ex.getCause() for the concrete failure.
  2. Ensure Jackson is available and a MappingJackson2HttpMessageConverter is set via setJsonMessageConverter.
  3. If a custom errorParametersConverter is registered, verify it handles null description/errorUri fields.
  4. Guard with try-catch and fall back to a plain 400 response body if serialization fails.

Example fix

// before
converter.write(oauth2Error, MediaType.APPLICATION_JSON, outputMessage);
// after
try {
    converter.write(oauth2Error, MediaType.APPLICATION_JSON, outputMessage);
} catch (HttpMessageNotWritableException ex) {
    logger.error("OAuth2 error serialization failed", ex.getCause());
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (oauth2Error.getErrorCode() == null) {
    throw new IllegalArgumentException("errorCode is required to serialize OAuth2Error");
}

Try / catch

try {
    converter.write(oauth2Error, MediaType.APPLICATION_JSON, outputMessage);
} catch (HttpMessageNotWritableException ex) {
    logger.error("OAuth2 error write failed", ex.getCause());
    outputMessage.getHeaders().setContentType(MediaType.TEXT_PLAIN);
}

Prevention

When it happens

Trigger: Calling writeInternal/write on an OAuth2ErrorHttpMessageConverter when the error-to-parameters converter throws or JSON serialization fails (no Jackson converter, broken output stream).

Common situations: Missing Jackson dependency, a custom errorParametersConverter that rejects an OAuth2Error with null errorCode, or an IOException while writing the body to a disconnected client.

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/dbd0e3221da390f8. Report an issue: GitHub.