spring-projects/spring-security · error · HttpMessageNotReadableException

An error occurred reading the OpenID Provider Configuration:

Error message

An error occurred reading the OpenID Provider Configuration: ${ex.getMessage()}

What it means

OidcProviderConfigurationHttpMessageConverter.readInternal deserializes a request body into an OidcProviderConfiguration. Any failure reading the JSON or converting the parameter map is wrapped in an HttpMessageNotReadableException with message "An error occurred reading the OpenID Provider Configuration: <cause message>". This converter backs the provider configuration endpoint, so in practice this error appears only when the endpoint is invoked in an unusual, non-standard way.

Source

Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/http/converter/OidcProviderConfigurationHttpMessageConverter.java:84

		this.jsonMessageConverter = converter;
	}

	@Override
	protected boolean supports(Class<?> clazz) {
		return OidcProviderConfiguration.class.isAssignableFrom(clazz);
	}

	@Override
	@SuppressWarnings("unchecked")
	protected OidcProviderConfiguration readInternal(Class<? extends OidcProviderConfiguration> clazz,
			HttpInputMessage inputMessage) throws HttpMessageNotReadableException {
		try {
			Map<String, Object> providerConfigurationParameters = (Map<String, Object>) this.jsonMessageConverter
				.read(STRING_OBJECT_MAP.getType(), null, inputMessage);
			return this.providerConfigurationConverter.convert(providerConfigurationParameters);
		}
		catch (Exception ex) {
			throw new HttpMessageNotReadableException(
					"An error occurred reading the OpenID Provider Configuration: " + ex.getMessage(), ex,
					inputMessage);
		}
	}

	@Override
	protected void writeInternal(OidcProviderConfiguration providerConfiguration, HttpOutputMessage outputMessage)
			throws HttpMessageNotWritableException {
		try {
			Map<String, Object> providerConfigurationResponseParameters = this.providerConfigurationParametersConverter
				.convert(providerConfiguration);
			this.jsonMessageConverter.write(providerConfigurationResponseParameters, STRING_OBJECT_MAP.getType(),
					MediaType.APPLICATION_JSON, outputMessage);
		}
		catch (Exception ex) {
			throw new HttpMessageNotWritableException(
					"An error occurred writing the OpenID Provider Configuration: " + ex.getMessage(), ex);
		}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Call the discovery endpoint with GET and no request body, as the OIDC Discovery spec requires.
  2. Inspect the nested cause message for the exact JSON parse or conversion failure and correct the body.
  3. Ensure Content-Type: application/json and a JSON-object body matching OidcProviderConfiguration fields if a body is genuinely required by a custom endpoint.
  4. If building a custom endpoint on this converter, register a custom Converter<Map<String,Object>, OidcProviderConfiguration> that accepts your payload.

Example fix

// before
curl -X POST https://server/.well-known/openid-configuration -d '{"issuer": 123}'

// after
curl https://server/.well-known/openid-configuration
Defensive patterns

Strategy: validation

Validate before calling

boolean isDiscoveryRequest(HttpServletRequest request) {
    return "GET".equalsIgnoreCase(request.getMethod())
        && (request.getContentLengthLong() <= 0);
}

Type guard

boolean isProviderConfigurationBody(Object body) {
    return body instanceof Map<?, ?> m && m.get("issuer") instanceof String;
}

Try / catch

try {
    OidcProviderConfiguration cfg = converter.read(OidcProviderConfiguration.class, inputMessage);
} catch (HttpMessageNotReadableException ex) {
    log.warn("Invalid provider configuration request: {}", ex.getCause() != null ? ex.getCause().getMessage() : ex.getMessage());
    response.sendError(HttpStatus.BAD_REQUEST.value());
}

Prevention

When it happens

Trigger: Any consumer sending a request body to the provider configuration endpoint (/.well-known/openid-configuration) via a path that uses this converter's read path with an unparseable or semantically invalid JSON body.

Common situations: Tests or tools POSTing bodies to a discovery endpoint that is normally GET-only; custom request matchers reusing this converter for a new endpoint; sending JSON that violates OidcProviderConfiguration's expected shape; content-type mismatches.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/419e94b6414330c6. Report an issue: GitHub.