elastic/elasticsearch · error · IllegalArgumentException

invalid parameters for header [{}]

Error message

invalid parameters for header [{}]

What it means

Thrown by ParsedMediaType.parseMediaType() when the parameter portion of the media type (everything after the first ';') is malformed. Each parameter must be a key=value pair with exactly one '=', no trailing space before '=', and no leading space after '='. Violating any of these produces this error.

Source

Thrown at libs/x-content/src/main/java/org/elasticsearch/xcontent/ParsedMediaType.java:86

            final String[] splitMediaType = elements[0].split("/");
            if ((splitMediaType.length == 2
                && TCHAR_PATTERN.matcher(splitMediaType[0].trim()).matches()
                && TCHAR_PATTERN.matcher(splitMediaType[1].trim()).matches()) == false) {
                throw new IllegalArgumentException("invalid media-type [" + headerValue + "]");
            }
            if (elements.length == 1) {
                return new ParsedMediaType(headerValue, splitMediaType[0].trim(), splitMediaType[1].trim(), new HashMap<>());
            } else {
                Map<String, String> parameters = new HashMap<>();
                for (int i = 1; i < elements.length; i++) {
                    String paramsAsString = elements[i].trim();
                    if (paramsAsString.isEmpty()) {
                        continue;
                    }
                    // spaces are allowed between parameters, but not between '=' sign
                    String[] keyValueParam = paramsAsString.split("=");
                    if (keyValueParam.length != 2 || hasTrailingSpace(keyValueParam[0]) || hasLeadingSpace(keyValueParam[1])) {
                        throw new IllegalArgumentException("invalid parameters for header [" + headerValue + "]");
                    }
                    String parameterName = keyValueParam[0].toLowerCase(Locale.ROOT).trim();
                    String parameterValue = keyValueParam[1].toLowerCase(Locale.ROOT).trim();
                    parameters.put(parameterName, parameterValue);
                }
                return new ParsedMediaType(
                    headerValue,
                    splitMediaType[0].trim().toLowerCase(Locale.ROOT),
                    splitMediaType[1].trim().toLowerCase(Locale.ROOT),
                    parameters
                );
            }
        }
        return null;
    }

    public static ParsedMediaType parseMediaType(XContentType requestContentType, Map<String, String> parameters) {
        ParsedMediaType parsedMediaType = requestContentType.toParsedMediaType();

View on GitHub (pinned to db6a809a66)

Solutions

  1. Remove spaces around the '=' sign in media type parameters.
  2. Use 'application/json; charset=utf-8' (no spaces around '=').
  3. Let the HTTP client library construct the Content-Type header rather than building it manually.
  4. Validate parameter format against RFC 7231 before sending.

Example fix

// before — space around '=' in parameter
Content-Type: application/json; charset = utf-8

// after — no spaces around '='
Content-Type: application/json; charset=utf-8
Defensive patterns

Strategy: validation

Validate before calling

// Validate parameter format: key=value with no spaces around '='
public static void validateMediaTypeParams(String header) {
    String[] parts = header.split(";", 2);
    if (parts.length == 2) {
        for (String param : parts[1].split(";")) {
            String[] kv = param.trim().split("=");
            if (kv.length != 2 || kv[0].isEmpty() || kv[0].endsWith(" ") || kv[1].startsWith(" ")) {
                throw new IllegalArgumentException("Invalid parameter format in: " + header);
            }
        }
    }
}

Try / catch

try {
    ParsedMediaType parsed = ParsedMediaType.parseMediaType(header);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("invalid parameters")) {
        return ResponseEntity.status(415).body("Malformed Content-Type parameters");
    }
    throw e;
}

Prevention

When it happens

Trigger: Sending a Content-Type like 'application/json; charset =utf-8' (space before '='), 'application/json; charset= utf-8' (space after '='), 'application/json; charset' (missing '='), or 'application/json; =utf8' (empty parameter name).

Common situations: Manually constructing Content-Type headers with spaces around the '=' sign. A proxy or middleware that reformats headers and introduces spaces. Copying a header from documentation that has formatting whitespace.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/67ff3eeb3ad962ab. Report an issue: GitHub.