quarkusio/quarkus · error · ErrorDataDecoderException

Error decoding charset attribute (wrapped NullPointerExcepti

Error message

Error decoding charset attribute (wrapped NullPointerException/IllegalArgumentException)

What it means

This ErrorDataDecoderException wraps a NullPointerException or IllegalArgumentException from factory.createAttribute() when decoding the charset parameter of a multipart disposition. The cleaned charset value was rejected (null/empty/illegal), aborting the multipart decode. It indicates a malformed charset= parameter in a Content-Disposition line.

Source

Thrown at independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/multipart/QuarkusMultipartResponseDecoder.java:785

                if (HttpHeaderValues.MULTIPART_MIXED.contentEqualsIgnoreCase(contents[1])) {
                    if (currentStatus == MultiPartStatus.DISPOSITION) {
                        String values = StringUtil.substringAfter(contents[2], '=');
                        multipartMixedBoundary = "--" + values;
                        currentStatus = MultiPartStatus.MIXEDDELIMITER;
                        return decodeMultipart(MultiPartStatus.MIXEDDELIMITER);
                    } else {
                        throw new ErrorDataDecoderException("Mixed Multipart found in a previous Mixed Multipart");
                    }
                } else {
                    for (int i = 1; i < contents.length; i++) {
                        final String charsetHeader = HttpHeaderValues.CHARSET.toString();
                        if (contents[i].regionMatches(true, 0, charsetHeader, 0, charsetHeader.length())) {
                            String values = StringUtil.substringAfter(contents[i], '=');
                            Attribute attribute;
                            try {
                                attribute = factory.createAttribute(response, charsetHeader, cleanString(values));
                            } catch (NullPointerException | IllegalArgumentException e) {
                                throw new ErrorDataDecoderException(e);
                            }
                            currentFieldAttributes.put(HttpHeaderValues.CHARSET, attribute);
                        } else {
                            Attribute attribute;
                            try {
                                attribute = factory.createAttribute(response,
                                        cleanString(contents[0]), contents[i]);
                            } catch (NullPointerException | IllegalArgumentException e) {
                                throw new ErrorDataDecoderException(e);
                            }
                            currentFieldAttributes.put(attribute.getName(), attribute);
                        }
                    }
                }
            }
        }
        // Is it a FileUpload
        Attribute filenameAttribute = currentFieldAttributes.get(HttpHeaderValues.FILENAME);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Fix the server to emit a valid charset value, e.g. charset="UTF-8", or omit the parameter entirely.
  2. Log/inspect the raw part headers to find the empty charset parameter.
  3. Sanitize the payload upstream (proxy or middleware) if the server cannot be changed.
  4. Ensure the client and server agree on encoding and rely on the default charset instead of sending charset explicitly.

Example fix

// before
Content-Disposition: form-data; name="txt"; charset=
// after
Content-Disposition: form-data; name="txt"; charset="UTF-8"
Defensive patterns

Strategy: validation

Validate before calling

// Validate charset parameter before emitting it
String charset = params.get("charset");
if (charset != null && (charset.isBlank() || !Charset.isSupported(charset.trim().replace("\"", "")))) {
    throw new IllegalStateException("Invalid charset disposition parameter: '" + charset + "'");
}

Type guard

static boolean isValidCharsetParam(String v) {
    return v != null && !v.isBlank() && Charset.isSupported(v.trim().replace("\"", ""));
}

Try / catch

try {
    decode(responseBody);
} catch (ErrorDataDecoderException e) {
    log.warn("Bad charset disposition attribute: {}", e.getCause(), e);
    throw new BadRequestException("Malformed charset parameter in multipart response", e);
}

Prevention

When it happens

Trigger: Within a mixed or plain multipart disposition, a parameter starting with 'charset' has an empty or invalid value after '=' (values = substringAfter gives empty/null), making createAttribute throw.

Common situations: Servers emitting 'charset=' with no value; broken template engines dropping the encoding value; custom clients copying headers incorrectly.

Related errors


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