quarkusio/quarkus · warning · BadRequestException

Malformed media type:

Error message

Malformed media type: 

What it means

getMediaTypeQualityValues() parses the Accept header expecting each item to be type/subtype. If no '/' is found in the remaining header, the item is not a valid media type and this BadRequestException is thrown.

Source

Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/request/AcceptHeaders.java:136

    /**
     * Gets the media types from a comma-separated list.
     *
     * @param header the header value.
     * @return the listed items in order of appearance or {@code null} if the header didn't contain any entries.
     */
    public static Map<MediaType, QualityValue> getMediaTypeQualityValues(String header) {
        if (header == null)
            return null;
        header = header.trim();
        if (header.length() == 0)
            return null;
        Map<MediaType, QualityValue> result = new LinkedHashMap<MediaType, QualityValue>();

        int offset = 0;
        while (offset >= 0) {
            int slashIndex = header.indexOf('/', offset);
            if (slashIndex < 0)
                throw new BadRequestException("Malformed media type: " + header);
            String type = header.substring(offset, slashIndex);
            String subtype;
            Map<String, String> parameters = null;
            QualityValue qualityValue = QualityValue.DEFAULT;

            offset = slashIndex + 1;
            int parameterStartIndex = header.indexOf(';', offset);
            int itemEndIndex = header.indexOf(',', offset);
            if (parameterStartIndex == itemEndIndex) {
                assert itemEndIndex == -1;
                subtype = header.substring(offset);
                offset = -1;
            } else if (itemEndIndex < 0 || (parameterStartIndex >= 0 && parameterStartIndex < itemEndIndex)) {
                subtype = header.substring(offset, parameterStartIndex);
                offset = parameterStartIndex + 1;
                parameters = new LinkedHashMap<String, String>();
                offset = parseParameters(parameters, header, offset);
                qualityValue = evaluateAcceptParameters(parameters);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Send a fully qualified media type such as application/json or text/plain in the Accept header
  2. Use */* if any content type is acceptable
  3. Fix the client library/configuration that emits the abbreviated media type

Example fix

// before
curl -H "Accept: json" ...
// after
curl -H "Accept: application/json" ...
Defensive patterns

Strategy: validation

Validate before calling

boolean allItemsAreMediaTypes(String accept) {
    if (accept == null) return false;
    for (String item : accept.split(",")) {
        String type = item.split(";")[0].trim();
        if (!type.equals("*") && !type.contains("/")) return false;
    }
    return true;
}

Type guard

boolean isMediaTypeToken(String s) {
    return s != null && s.matches("[\*a-zA-Z0-9!#$&^_.+-]+/[\*a-zA-Z0-9!#$&^_.+-]+.*");
}

Try / catch

try {
    types = AcceptHeaders.getMediaTypeQualityValues(accept);
} catch (BadRequestException e) {
    types = Map.of(MediaType.WILDCARD, QualityValue.HIGHEST);
}

Prevention

When it happens

Trigger: Accept header containing an item without a slash, e.g. 'Accept: text' or 'Accept: *,*/2' handling offsets that skip past items.

Common situations: Hand-crafted curl requests with abbreviated media types; misconfigured API clients sending bare tokens like 'json' instead of 'application/json'; HTML forms or custom user-agents with wrong Accept values.

Understand the failure class

Related errors


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