{"record":{"id":"a510717884ff4b35","repo":"quarkusio/quarkus","slug":"error-decoding-content-length-attribute-wrapped-n","errorCode":null,"errorMessage":"Error decoding content-length attribute (wrapped NullPointerException/IllegalArgumentException)","messagePattern":"Error decoding content-length attribute \\(wrapped NullPointerException/IllegalArgumentException\\)","errorType":"exception","errorClass":"ErrorDataDecoderException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/multipart/QuarkusMultipartResponseDecoder.java","lineNumber":761,"sourceCode":"                    }\n                }\n            } else if (HttpHeaderNames.CONTENT_TRANSFER_ENCODING.contentEqualsIgnoreCase(contents[0])) {\n                Attribute attribute;\n                try {\n                    attribute = factory.createAttribute(response, HttpHeaderNames.CONTENT_TRANSFER_ENCODING.toString(),\n                            cleanString(contents[1]));\n                } catch (NullPointerException | IllegalArgumentException e) {\n                    throw new ErrorDataDecoderException(e);\n                }\n\n                currentFieldAttributes.put(HttpHeaderNames.CONTENT_TRANSFER_ENCODING, attribute);\n            } else if (HttpHeaderNames.CONTENT_LENGTH.contentEqualsIgnoreCase(contents[0])) {\n                Attribute attribute;\n                try {\n                    attribute = factory.createAttribute(response, HttpHeaderNames.CONTENT_LENGTH.toString(),\n                            cleanString(contents[1]));\n                } catch (NullPointerException | IllegalArgumentException e) {\n                    throw new ErrorDataDecoderException(e);\n                }\n\n                currentFieldAttributes.put(HttpHeaderNames.CONTENT_LENGTH, attribute);\n            } else if (HttpHeaderNames.CONTENT_TYPE.contentEqualsIgnoreCase(contents[0])) {\n                // Take care of possible \"multipart/mixed\"\n                if (HttpHeaderValues.MULTIPART_MIXED.contentEqualsIgnoreCase(contents[1])) {\n                    if (currentStatus == MultiPartStatus.DISPOSITION) {\n                        String values = StringUtil.substringAfter(contents[2], '=');\n                        multipartMixedBoundary = \"--\" + values;\n                        currentStatus = MultiPartStatus.MIXEDDELIMITER;\n                        return decodeMultipart(MultiPartStatus.MIXEDDELIMITER);\n                    } else {\n                        throw new ErrorDataDecoderException(\"Mixed Multipart found in a previous Mixed Multipart\");\n                    }\n                } else {\n                    for (int i = 1; i < contents.length; i++) {\n                        final String charsetHeader = HttpHeaderValues.CHARSET.toString();\n                        if (contents[i].regionMatches(true, 0, charsetHeader, 0, charsetHeader.length())) {","sourceCodeStart":743,"sourceCodeEnd":779,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/multipart/QuarkusMultipartResponseDecoder.java#L743-L779","documentation":"This ErrorDataDecoderException wraps a NullPointerException or IllegalArgumentException raised by factory.createAttribute() while decoding the Content-Length disposition attribute of a multipart part. The decoder cannot build a valid attribute from the cleaned header value and fails the entire decode. It signals a malformed or missing Content-Length parameter inside the part's Content-Disposition/header block.","triggerScenarios":"The multipart part carries 'Content-Length=' with an empty or invalid value (e.g. no value after '=', non-numeric or control characters), causing createAttribute to throw NPE/IAE.","commonSituations":"Hand-rolled or buggy server multipart writers emitting empty Content-Length parameters; proxies that truncate header values; misconfigured gateway mangling part headers.","solutions":["Capture the response body (logging) and correct the Content-Length parameter emitted by the server, or remove it entirely (it is optional).","Verify no '=' value is missing/empty in the part header line.","Update or fix the server-side multipart serialization library.","As a workaround, route the response through a proxy that normalizes part headers, or decode with a tolerant custom factory."],"exampleFix":"// before (server output)\nContent-Disposition: form-data; name=\"data\"; Content-Length=\n// after\nContent-Disposition: form-data; name=\"data\"; Content-Length=\"42\"","handlingStrategy":"validation","validationCode":"// Ensure Content-Length disposition param, if present, is a positive integer\nString cl = params.get(\"Content-Length\");\nif (cl != null && !cl.chars().allMatch(Character::isDigit)) {\n    throw new IllegalStateException(\"Content-Length disposition param must be numeric, got: \" + cl);\n}","typeGuard":"static boolean isValidContentLength(String v) {\n    return v == null || (!v.isBlank() && v.chars().allMatch(Character::isDigit));\n}","tryCatchPattern":"try {\n    decoder.decodeMultipart(status);\n} catch (ErrorDataDecoderException e) {\n    log.error(\"Failed decoding Content-Length disposition attribute: {}\", e.getCause(), e);\n    throw new MalformedMultipartException(e);\n}","preventionTips":["Prefer omitting Content-Length in dispositions; the decoder does not require it.","Verify proxies/gateways do not truncate part header values.","Add contract tests asserting the exact multipart body shape from your server.","Escape values with quotes to survive '=' and ';' characters."],"tags":["multipart","http-client","decoding","resteasy-reactive"],"backgroundTag":"multipart-decode-failed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}