{"record":{"id":"a958f73f0c3893d9","repo":"quarkusio/quarkus","slug":"illegal-charset-in-multipart-response-content-type","errorCode":null,"errorMessage":"Illegal charset in multipart response Content-Type (wrapped)","messagePattern":"Illegal charset in multipart response Content-Type \\(wrapped\\)","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":227,"sourceCode":"            Charset charset) {\n        this.response = checkNotNull(response, \"request\");\n        this.charset = checkNotNull(charset, \"charset\");\n        this.factory = checkNotNull(factory, \"factory\");\n        // Fill default values\n\n        String contentTypeValue = this.response.headers().get(HttpHeaderNames.CONTENT_TYPE);\n        if (contentTypeValue == null) {\n            throw new ErrorDataDecoderException(\"No '\" + HttpHeaderNames.CONTENT_TYPE + \"' header present.\");\n        }\n\n        String[] dataBoundary = getMultipartDataBoundary(contentTypeValue);\n        if (dataBoundary != null) {\n            multipartDataBoundary = dataBoundary[0];\n            if (dataBoundary.length > 1 && dataBoundary[1] != null) {\n                try {\n                    this.charset = Charset.forName(dataBoundary[1]);\n                } catch (IllegalCharsetNameException e) {\n                    throw new ErrorDataDecoderException(e);\n                }\n            }\n        } else {\n            destroy();\n            throw new ErrorDataDecoderException(\"Unable to parse multipart response - No delimiter specified\");\n        }\n        currentStatus = MultiPartStatus.HEADERDELIMITER;\n\n        try {\n            if (this.response instanceof HttpContent) {\n                // Offer automatically if the given request is als type of HttpContent\n                // See #1089\n                offer((HttpContent) this.response);\n            } else {\n                parseBody();\n            }\n        } catch (Throwable e) {\n            destroy();","sourceCodeStart":209,"sourceCodeEnd":245,"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#L209-L245","documentation":"When the Content-Type header of a multipart response declares a charset parameter whose name is not a legal charset name, Charset.forName throws IllegalCharsetNameException, which is wrapped into an ErrorDataDecoderException. This indicates a malformed charset= parameter in the response's Content-Type header.","triggerScenarios":"Response Content-Type like multipart/mixed; boundary=...; charset=<invalid name> where the charset name contains characters that are not legal charset-name syntax (e.g. spaces, '*', '=') — not merely an unknown charset.","commonSituations":"Server frameworks or custom code emitting a malformed charset parameter (e.g. charset=UTF_8 or charset=\"utf 8\"); proxies rewriting Content-Type incorrectly.","solutions":["Fix the server to emit a valid charset name such as UTF-8","Log the raw Content-Type header to identify the malformed value","Catch ErrorDataDecoderException and re-try decoding with a forced default charset if the library API allows","Reject or sanitize the response at the proxy/gateway layer"],"exampleFix":"// before (server)\nContent-Type: multipart/mixed; boundary=xyz; charset=utf 8\n// after\nContent-Type: multipart/mixed; boundary=xyz; charset=UTF-8","handlingStrategy":"validation","validationCode":"String ct = response.headers().get(HttpHeaderNames.CONTENT_TYPE);\nfor (String p : ct.split(\";\")) {\n    p = p.trim();\n    if (p.startsWith(\"charset=\")) {\n        String name = p.substring(8).replace(\"\\\"\", \"\");\n        if (!Charset.isSupported(name)) throw new IllegalArgumentException(\"Illegal charset: \" + name);\n    }\n}","typeGuard":null,"tryCatchPattern":"try { new QuarkusMultipartResponseDecoder(response, factory, charset); } catch (ErrorDataDecoderException e) { log.error(\"Bad charset in Content-Type\", e.getCause()); }","preventionTips":["Sanitize charset parameters at the gateway","Only accept charset values passing Charset.isSupported/isValid name check"],"tags":["http","multipart","charset"],"backgroundTag":"illegal-charset-name","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"}