hs-web/hsweb-framework · warning · UnsupportedMediaTypeStatusException
unsupported_media_type
unsupported_media_type
Error message
error.unsupported_media_type
What it means
WebFlux's UnsupportedMediaTypeStatusException is translated to HTTP 415 with code unsupported_media_type, the localized 'error.unsupported_media_type' message, and the list of supported media types attached to the response result. It means the client sent a body with a Content-Type the endpoint cannot consume.
Solutions
- Set the request Content-Type header to a type the endpoint supports (see supportedMediaTypes in the response body).
- If sending JSON, use application/json and serialize the body correctly.
- If the endpoint should accept another type, register a HttpMessageReader/decoder for that media type in the server codec configuration.
- Check proxies/gateways for headers stripped or rewritten.
Example fix
// before
fetch('/api/user', {method:'POST', body: JSON.stringify(u)}) // no Content-Type
// after
fetch('/api/user', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(u)}) Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = ['application/json'];
if (!SUPPORTED.includes(headers['Content-Type'])) {
throw new Error(`Unsupported Content-Type: ${headers['Content-Type']}; use application/json`);
} Try / catch
try {
return await client.post(url, body, { headers: { 'Content-Type': 'application/json' } });
} catch (e) {
if (e.response && e.response.status === 415) {
console.warn('415: use one of', e.response.data.result);
}
throw e;
} Prevention
- Always set Content-Type explicitly in HTTP clients.
- Read the supportedMediaTypes from the 415 response before retrying.
- Keep server codec configuration in sync with documented media types.
- Test clients against real endpoints with contract tests.
When it happens
Trigger: POST/PUT with Content-Type like text/plain or application/x-www-form-urlencoded to an endpoint that decodes @RequestBody as JSON/other; missing Content-Type header where none can be inferred; Accept on the client forcing an unsupported writer during encoding.
Common situations: Older HTTP clients or curl defaults (application/x-www-form-urlencoded) posting JSON; misconfigured gateway rewriting Content-Type; API consumers ignoring the documented media type.
Related errors
AI-assisted analysis of hs-web/hsweb-framework@b2cfc85a57 (2026-09-13).
Data as JSON: /api/errors/8e8ed7893117ef3d.
Report an issue: GitHub.
Appendix: source
Thrown at hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonErrorControllerAdvice.java:235
return LocaleUtils
.resolveThrowable(e, (err, msg) -> {
log.warn(msg, e);
return ResponseMessage.error(400, CodeConstants.Error.illegal_argument, msg);
});
}
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Mono<ResponseMessage<Object>> handleException(AuthenticationException e) {
return LocaleUtils
.resolveThrowable(e, (err, msg) -> ResponseMessage.error(400, err.getCode(), msg));
}
@ExceptionHandler
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
public Mono<ResponseMessage<Object>> handleException(UnsupportedMediaTypeStatusException e) {
log.warn(e.getLocalizedMessage(), e);
return LocaleUtils
.resolveMessageReactive("error.unsupported_media_type")
.map(msg -> ResponseMessage
.error(415, "unsupported_media_type", msg)
.result(e.getSupportedMediaTypes()));
}
@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
public Mono<ResponseMessage<Object>> handleException(NotAcceptableStatusException e) {
log.warn(e.getLocalizedMessage(), e);
return LocaleUtils
.resolveMessageReactive("error.not_acceptable_media_type")
.map(msg -> ResponseMessage
.error(406, "not_acceptable_media_type", msg)
.result(e.getSupportedMediaTypes()));View on GitHub (pinned to b2cfc85a57)