quarkusio/quarkus · error · ErrorDataDecoderException
Error decoding content-transfer-encoding attribute (wrapped
Error message
Error decoding content-transfer-encoding attribute (wrapped NullPointerException/IllegalArgumentException)
What it means
This ErrorDataDecoderException wraps a NullPointerException or IllegalArgumentException thrown while creating the content-transfer-encoding attribute during multipart response parsing. The HttpPostStandardBodyDataFactory (attribute factory) rejected the attribute name or the cleaned header value, so the decoder aborts the whole multipart decode. It indicates a malformed Content-Transfer-Encoding disposition parameter in the multipart response body.
Source
Thrown at independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/multipart/QuarkusMultipartResponseDecoder.java:751
// read next values and store them in the map as Attribute
for (int i = 2; i < contents.length; i++) {
String[] values = contents[i].split("=", 2);
Attribute attribute;
try {
attribute = getContentDispositionAttribute(values);
} catch (NullPointerException | IllegalArgumentException e) {
throw new ErrorDataDecoderException(e);
}
currentFieldAttributes.put(attribute.getName(), attribute);
}
}
} else if (HttpHeaderNames.CONTENT_TRANSFER_ENCODING.contentEqualsIgnoreCase(contents[0])) {
Attribute attribute;
try {
attribute = factory.createAttribute(response, HttpHeaderNames.CONTENT_TRANSFER_ENCODING.toString(),
cleanString(contents[1]));
} catch (NullPointerException | IllegalArgumentException e) {
throw new ErrorDataDecoderException(e);
}
currentFieldAttributes.put(HttpHeaderNames.CONTENT_TRANSFER_ENCODING, attribute);
} else if (HttpHeaderNames.CONTENT_LENGTH.contentEqualsIgnoreCase(contents[0])) {
Attribute attribute;
try {
attribute = factory.createAttribute(response, HttpHeaderNames.CONTENT_LENGTH.toString(),
cleanString(contents[1]));
} catch (NullPointerException | IllegalArgumentException e) {
throw new ErrorDataDecoderException(e);
}
currentFieldAttributes.put(HttpHeaderNames.CONTENT_LENGTH, attribute);
} else if (HttpHeaderNames.CONTENT_TYPE.contentEqualsIgnoreCase(contents[0])) {
// Take care of possible "multipart/mixed"
if (HttpHeaderValues.MULTIPART_MIXED.contentEqualsIgnoreCase(contents[1])) {
if (currentStatus == MultiPartStatus.DISPOSITION) {
String values = StringUtil.substringAfter(contents[2], '=');View on GitHub (pinned to e1c734241f)
Solutions
- Inspect the raw multipart response body (enable wire logging) and fix the malformed Content-Transfer-Encoding parameter on the server.
- Check the value after 'Content-Transfer-Encoding=' is non-empty and contains no control characters or stray quotes.
- If the server cannot be fixed, sanitize/normalize the response before decoding or use a custom AttributeFactory tolerant of the value.
- Compare with a working client (e.g. curl) to confirm the header difference and report/fix the server-side multipart writer.
Example fix
// before (malformed server output) Content-Disposition: form-data; name="file"; Content-Transfer-Encoding= // after (well-formed) Content-Disposition: form-data; name="file"; Content-Transfer-Encoding="binary"
Defensive patterns
Strategy: validation
Validate before calling
// Validate the disposition parameter before the server sends it (server-side check)
String cte = params.get("Content-Transfer-Encoding");
if (cte == null || cte.isBlank()) {
throw new IllegalStateException("Content-Transfer-Encoding must have a non-empty value");
} Type guard
static boolean isValidDispositionValue(String v) {
return v != null && !v.isBlank() && v.chars().allMatch(c -> c >= 0x20 && c != 0x7f);
} Try / catch
try {
List<HttpResponsePart> parts = decoder.decode(...);
} catch (ErrorDataDecoderException e) {
log.warn("Malformed multipart disposition (Content-Transfer-Encoding): {}", e.getMessage(), e);
throw new BadRequestException("Malformed multipart response", e);
} Prevention
- Always emit quoted, non-empty values for disposition parameters.
- Wire-log responses during integration to catch malformed part headers early.
- Test against real server output, not hand-written multipart samples.
- Keep server multipart serializer libraries up to date.
When it happens
Trigger: The multipart response contains a Content-Transfer-Encoding disposition attribute whose value, after cleanString(), is null or otherwise rejected by factory.createAttribute() (e.g. missing value after '=', empty token, or illegal characters).
Common situations: Non-Quarkus/Netty-incompatible servers or proxies emitting hand-crafted multipart bodies; server frameworks producing 'Content-Transfer-Encoding:' with no value; custom response transformations that mangle disposition headers.
Related errors
- Error decoding content-length attribute (wrapped NullPointer
- Error decoding charset attribute (wrapped NullPointerExcepti
- Error decoding multipart attribute (wrapped NullPointerExcep
- setting content of MultiByteHttpData is not supported
- adding content to MultiByteHttpData is not supported
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/672a14f114be8896.
Report an issue: GitHub.