quarkusio/quarkus · error · NotSupportedException

NotSupportedException

Error message

NotSupportedException

What it means

NotSupportedException (HTTP 405/406 family) is thrown by ReaderInterceptorContextImpl.proceed() when, after re-discovering message body readers for the requested type and media type, no MessageBodyReader is found. It means the server has no provider capable of deserializing the request body into the target Java type for the given Content-Type.

Source

Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/ReaderInterceptorContextImpl.java:48

    public ReaderInterceptorContextImpl(ResteasyReactiveRequestContext context, Annotation[] annotations, Class<?> type,
            Type genericType, MediaType mediaType, MessageBodyReader reader, InputStream inputStream,
            ReaderInterceptor[] interceptors, ServerSerialisers serialisers) {
        super(context, annotations, type, genericType, mediaType, serialisers);
        this.reader = reader;
        this.inputStream = inputStream;
        this.interceptors = interceptors;
        this.headers.putAll(context.getHttpHeaders().getRequestHeaders());
    }

    @Override
    public Object proceed() throws IOException, WebApplicationException {
        if (index == interceptors.length) {
            MessageBodyReader effectiveReader = reader;
            if (rediscoveryNeeded) {
                List<MessageBodyReader<?>> readers = serialisers.findReaders(null, type, mediaType, RuntimeType.SERVER);
                if (readers.isEmpty()) {
                    throw new NotSupportedException();
                }
                effectiveReader = readers.get(0);
            }
            return effectiveReader.readFrom(type, genericType, annotations, mediaType, headers, inputStream);
        } else {
            return interceptors[index++].aroundReadFrom(this);
        }
    }

    @Override
    public InputStream getInputStream() {
        return inputStream;
    }

    @Override
    public void setInputStream(InputStream is) {
        this.inputStream = is;
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add/register a MessageBodyReader for the type+mediaType pair (e.g. include quarkus-rest-jackson or quarkus-rest-jsonb).
  2. Make the client send a Content-Type matching an @Consumes value of the resource method.
  3. Fix the custom ReaderInterceptor so it does not change the type/mediaType to something unsupported, or avoid forcing rediscovery.
  4. Check the resource method's @Consumes annotation includes the incoming media type.

Example fix

// before (client)
curl -H 'Content-Type: text/plain' -d '{"name":"a"}' /api/items
// after
curl -H 'Content-Type: application/json' -d '{"name":"a"}' /api/items
Defensive patterns

Strategy: validation

Validate before calling

// client side: ensure Content-Type matches what the endpoint can read
if (!contentType.equals(MediaType.APPLICATION_JSON)) {
    throw new IllegalArgumentException("Endpoint only accepts application/json");
}

Try / catch

try {
    return interceptorContext.proceed();
} catch (NotSupportedException e) {
    throw new WebApplicationException("Unsupported media type for body", 415);
}

Prevention

When it happens

Trigger: A ReaderInterceptor chain reaches the end and rediscoveryNeeded is true (the original reader was invalidated, e.g. after an interceptor changed the type or media type), and serialisers.findReaders() returns an empty list for (type, mediaType, SERVER).

Common situations: Client sends a request body with a Content-Type the endpoint cannot consume (e.g. text/plain into a JSON-mapped POJO); a custom ReaderInterceptor modifies the media type or generic type so the pre-selected reader no longer applies; missing JSON extension (quarkus-rest-jackson) so only a few built-in readers exist.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7b342063728a855c. Report an issue: GitHub.