spring-projects/spring-security · error · HttpMessageNotWritableException
This converter cannot write a…
Error message
This converter cannot write a RelyingPartyRegistration.Builder
What it means
OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverter only supports reading (converting metadata bytes into a RelyingPartyRegistration.Builder). Its write operation is intentionally unimplemented and always throws HttpMessageNotWritableException. If Spring MVC tries to serialize a RelyingPartyRegistration.Builder as an HTTP response body, this error occurs.
Solutions
- Call .build() on the RelyingPartyRegistration.Builder and return the RelyingPartyRegistration (or a DTO/metadata view) instead
- If you need to emit SP metadata, use OpenSaml metadata generation endpoints (e.g. spring.security saml metadata filter) rather than this converter
- Return a different response representation (Map, ResponseEntity<String>) so this converter isn't selected
Example fix
// before
@GetMapping("/registration")
public RelyingPartyRegistration.Builder registration() { return builder; }
// after
@GetMapping("/registration")
public RelyingPartyRegistration registration() { return builder.build(); } Defensive patterns
Strategy: type-guard
Validate before calling
Object body = controllerReturnValue;
if (body instanceof RelyingPartyRegistration.Builder) {
throw new IllegalStateException("Return RelyingPartyRegistration, not its Builder");
} Type guard
boolean isWritable(Object body) {
return !(body instanceof RelyingPartyRegistration.Builder);
} Try / catch
// Avoid at runtime by design; if writing a generic handler:
try {
converter.write(builder, contentType, outputMessage);
} catch (HttpMessageNotWritableException ex) {
throw new UnsupportedOperationException("Read-only converter; build the registration first", ex);
} Prevention
- Never return RelyingPartyRegistration.Builder from controllers; always .build() first
- Remember this converter is read-only (metadata -> Builder)
- Review @RequestMapping return types for accidental Builder leaks
When it happens
Trigger: Returning a RelyingPartyRegistration.Builder (or a type resolving to this converter) from a @RestController method, or calling converter.write(...) directly; HttpMessageNotWritableException thrown from write().
Common situations: Controller accidentally returns the Builder instead of a built RelyingPartyRegistration or a DTO; developer assumes the converter is bidirectional; misconfigured message converters pick this converter for the response.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- A Bean named mvcHandlerMappingIntrospector of type…
- A Bean named mvcHandlerMappingIntrospector of type…
- An error occurred reading the OAuth 2.0 Client…
- An error occurred writing the OAuth 2.0 Authorization…
- An error occurred writing the OAuth 2.0 Client…
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/18c105fc830d34ad.
Report an issue: GitHub.
Appendix: source
Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/registration/OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverter.java:91
public boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType) {
return false;
}
@Override
public List<MediaType> getSupportedMediaTypes() {
return Arrays.asList(MediaType.APPLICATION_XML, MediaType.TEXT_XML);
}
@Override
public RelyingPartyRegistration.Builder read(Class<? extends RelyingPartyRegistration.Builder> clazz,
HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return RelyingPartyRegistrations.fromMetadata(inputMessage.getBody());
}
@Override
public void write(RelyingPartyRegistration.Builder builder, @Nullable MediaType contentType,
HttpOutputMessage outputMessage) throws HttpMessageNotWritableException {
throw new HttpMessageNotWritableException("This converter cannot write a RelyingPartyRegistration.Builder");
}
}
View on GitHub (pinned to 96852e8860)