quarkusio/quarkus · error · IllegalArgumentException

Failed to parse media type

Error message

Failed to parse media type 

What it means

MediaTypeHeaderDelegate.internalParse splits a media type string on '/' and parameters. When no '/' is present (typeIndex == -1), the whole string is treated as the major type, which is only legal if it is the wildcard '*'. Any other bare token (e.g. "json", "text") throws IllegalArgumentException("Failed to parse media type " + type).

Source

Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/headers/MediaTypeHeaderDelegate.java:77

            map.put(type, result);
            reverseMap.put(result, internalToString(result));
        }
        return result;
    }

    private static MediaType internalParse(String type) {
        int typeIndex = type.indexOf('/');
        int paramIndex = type.indexOf(';');
        String major = null;
        String subtype = null;
        if (typeIndex < 0) // possible "*"
        {
            major = type;
            if (paramIndex > -1) {
                major = major.substring(0, paramIndex);
            }
            if (!MediaType.MEDIA_TYPE_WILDCARD.equals(major)) {
                throw new IllegalArgumentException("Failed to parse media type " + type);
            }
            subtype = MediaType.MEDIA_TYPE_WILDCARD;
        } else {
            major = type.substring(0, typeIndex);
            if (paramIndex > -1) {
                if (typeIndex + 1 > paramIndex) {
                    throw new IllegalArgumentException("Failed to parse media type " + type);
                }
                subtype = type.substring(typeIndex + 1, paramIndex);
            } else {
                subtype = type.substring(typeIndex + 1);
            }
        }
        if (major.length() < 1 || subtype.length() < 1) {
            throw new IllegalArgumentException("Failed to parse media type " + type);
        }
        if (!isValid(major) || !isValid(subtype)) {
            throw new IllegalArgumentException("Failed to parse media type " + type);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change the media type to full type/subtype form: "json" → "application/json", "*" → "*/*" (the sole legal slash-less form).
  2. Check the raw header/annotation value contains '/' and a non-empty subtype before passing to MediaType.valueOf.
  3. Use MediaType constants (MediaType.APPLICATION_JSON, MediaType.WILDCARD_TYPE) instead of hand-written strings.
  4. Catch IllegalArgumentException around MediaType.valueOf and return HTTP 415/400 appropriately for client-supplied headers.

Example fix

// before
@Produces("json") // throws when parsed
// after
@Produces("application/json")
Defensive patterns

Strategy: validation

Validate before calling

Pattern MEDIA_TYPE = Pattern.compile("^[^/]+/[^;]+(;.*)?$");
boolean isParsableMediaType(String type) {
    return type != null && ("*".equals(type.trim()) || MEDIA_TYPE.matcher(type.trim()).matches());
}

Try / catch

try {
    MediaType mt = MediaType.valueOf(type);
} catch (IllegalArgumentException e) {
    throw new NotAcceptableException("Unsupported media type: " + type);
}

Prevention

When it happens

Trigger: Parsing a media type string with no slash that is not exactly "*": MediaType.valueOf("json"), @Produces("plain/text"-style typos like "text" alone), or a Content-Type header value of just "application".

Common situations: Typo'd @Produces/@Consumes annotations missing the '/'; config values (quarkus.* content types) set to bare tokens; clients sending malformed Content-Type/Accept headers; string constants built by concatenation that dropped the subtype.

Understand the failure class

Related errors


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