quarkusio/quarkus · error · ErrorDataDecoderException

Mixed Multipart found in a previous Mixed Multipart

Error message

Mixed Multipart found in a previous Mixed Multipart

What it means

The decoder encountered a nested 'multipart/mixed' Content-Type inside a part that is already being parsed as a mixed-multipart child. Nested mixed multiparts are not supported, so parsing fails with ErrorDataDecoderException. This protects the state machine from unsupported recursive multipart structures.

Source

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

                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], '=');
                        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]);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Flatten the payload on the server so mixed multipart is not nested inside another mixed multipart.
  2. If nested mixed content is required, pre-process the raw body yourself (e.g. parse the outer layer and feed inner parts separately) instead of relying on the decoder.
  3. Switch the parts to a simple multipart/form-data structure without the mixed wrapper.
  4. File/track a feature request if your protocol genuinely needs nested mixed support.

Example fix

// before (nested, unsupported)
Content-Type: multipart/mixed; boundary=outer
  Content-Type: multipart/mixed; boundary=inner
// after (flattened)
Content-Type: multipart/mixed; boundary=outer
  Content-Type: application/octet-stream
Defensive patterns

Strategy: validation

Validate before calling

// Detect nested multipart/mixed before sending the response
if (isMixedMultipart(partContentType) && parentStatus == MIXED) {
    throw new IllegalStateException("Nested multipart/mixed is not supported by the client decoder");
}

Try / catch

try {
    response = client.multipartCall().await();
} catch (BadRequestException e) {
    if (e.getCause() instanceof ErrorDataDecoderException
            && e.getCause().getMessage().contains("Mixed Multipart")) {
        // fall back to raw-body handling / custom parser
        response = client.rawCall().await();
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: A part within a multipart/mixed section itself declares Content-Type: multipart/mixed (currentStatus is DISPOSITION while already in mixed mode), so the state machine cannot transition to MIXEDDELIMITER twice.

Common situations: Servers implementing RFC-allowed but rarely-used nested multipart/mixed payloads (e.g. some email-like or SOAP-with-attachments stacks); middleware aggregating multipart payloads recursively.

Related errors


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