quarkusio/quarkus · error · BadRequestException

Malformed parameter:

Error message

Malformed parameter: 

What it means

AcceptHeaders.getStringQualityValues throws a BadRequestException while parsing an Accept-style header when a parameter segment lacks an '=' separator, e.g. Accept: text/html;q. Quality parameters must be name=value pairs (normally q=0.5). A malformed parameter causes the whole header parse to be rejected with 400.

Source

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

        int offset = 0;
        while (true) {
            int endIndex = header.indexOf(',', offset);
            String content;
            if (endIndex < 0) {
                content = header.substring(offset);
            } else {
                content = header.substring(offset, endIndex);
            }

            QualityValue qualityValue = QualityValue.DEFAULT;
            int qualityIndex = content.indexOf(';');
            if (qualityIndex >= 0) {
                String parameter = content.substring(qualityIndex + 1);
                content = content.substring(0, qualityIndex);

                int equalsIndex = parameter.indexOf('=');
                if (equalsIndex < 0) {
                    throw new BadRequestException("Malformed parameter: " + parameter);
                }
                String name = parameter.substring(0, equalsIndex).trim();
                if (!"q".equals(name)) {
                    throw new BadRequestException("Unsupported parameter: " + parameter);
                }
                String value = parameter.substring(equalsIndex + 1).trim();
                qualityValue = QualityValue.valueOf(value);
            }

            content = content.trim();
            if (content.length() == 0) {
                throw new BadRequestException("Empty Field in header: " + header);
            }
            if (content.equals("*")) {
                result.put(null, qualityValue);
            } else {
                result.put(content, qualityValue);
            }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Fix the client to send well-formed parameters: text/html;q=0.9 instead of text/html;q.
  2. Strip or correct the malformed header in any proxy/middleware that rewrites it.
  3. Reproduce with curl using a minimal valid header to confirm, then update the offending client code.
  4. Server-side: catch BadRequestException via an exception mapper to return a clearer 400 message if you must tolerate bad clients.

Example fix

// before
curl -H "Accept: text/html;q" ...
// after
curl -H "Accept: text/html;q=0.9" ...
Defensive patterns

Strategy: try-catch

Validate before calling

boolean wellFormed = header == null || Arrays.stream(header.split(",")).allMatch(p -> { int i = p.indexOf(';'); return i < 0 || Arrays.stream(p.substring(i+1).split(";")) .allMatch(kv -> kv.isBlank() || kv.contains("="))); });

Try / catch

try { parseAccept(header); } catch (BadRequestException e) { log.warnf("bad header %s: %s", header, e.getMessage()); return defaultQualityValues(); }

Prevention

When it happens

Trigger: A client sends an Accept (or similar) header whose parameter after ';' has no '=' sign, e.g. "text/html; q" or "application/json;q;level=1".

Common situations: Hand-written or buggy client headers; broken interceptors/proxies rewriting headers; malformed Accept headers from custom HTTP clients or tests.

Understand the failure class

Related errors


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