{"record":{"id":"effed8d72b3fa649","repo":"quarkusio/quarkus","slug":"connection-terminated-parsing-multipart-request","errorCode":null,"errorMessage":"Connection terminated parsing multipart request","messagePattern":"Connection terminated parsing multipart request","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"warning","filePath":"independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java","lineNumber":277,"sourceCode":"\n        @Override\n        public FormData parseBlocking() throws Exception {\n            final FormData existing = exchange.getFormData();\n            if (existing != null) {\n                return existing;\n            }\n            try (InputStream inputStream = exchange.getInputStream()) {\n                byte[] buf = new byte[1024];\n                int c;\n                while ((c = inputStream.read(buf)) > 0) {\n                    try {\n                        parser.parse(ByteBuffer.wrap(buf, 0, c));\n                    } catch (MultipartParser.HeaderTooLargeException e) {\n                        throw new WebApplicationException(Response.Status.REQUEST_ENTITY_TOO_LARGE);\n                    }\n                }\n                if (!parser.isComplete()) {\n                    throw new IOException(\"Connection terminated parsing multipart request\");\n                }\n                exchange.setFormData(data);\n            }\n            return data;\n        }\n\n        @Override\n        public void beginPart(final CaseInsensitiveMap<String> headers) {\n            this.currentFileSize = 0;\n            this.headers = headers;\n            final String disposition = headers.getFirst(HttpHeaders.CONTENT_DISPOSITION);\n            if (disposition != null) {\n                if (disposition.startsWith(\"form-data\")) {\n                    currentName = HeaderUtil.extractQuotedValueFromHeader(disposition, \"name\");\n                    fileName = HeaderUtil.sanitizeFileName(\n                            HeaderUtil.extractQuotedValueFromHeaderWithEncoding(disposition, \"filename\"));\n                    String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);\n                    if (((fileName != null) || isFileContentType(contentType) || fileFormNames.contains(currentName))","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java#L259-L295","documentation":"MultiPartParserDefinition.parseBlocking throws this IOException when the HTTP connection ends before the multipart body has been fully parsed. The parser never reached a complete state, so the form data is incomplete and cannot be handed to the request. Typically the client closed or aborted the connection mid-upload.","triggerScenarios":"Client disconnects or times out while sending a multipart/form-data body; Content-Length larger than the data actually sent; network interruption during a blocking multipart parse loop.","commonSituations":"Slow mobile clients dropping uploads; proxy/gateway timeouts cutting long uploads; client-side fetch cancellation; broken upload scripts that close the stream early.","solutions":["Retry the upload from the client with resumable/chunked upload support for large files.","Check client code for early stream close or incorrect Content-Length headers.","Increase proxy/gateway and server timeouts (quarkus.http.idle-timeout) for large uploads.","Handle IOException / client aborts server-side gracefully; log and return a 400 instead of a 500."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// client-side: ensure content-length matches body size before sending\nlong bodySize = computeBodySize(); if (bodySize != declaredLength) throw new IllegalStateException(\"length mismatch\");","typeGuard":null,"tryCatchPattern":"try { parseMultipart(exchange); } catch (IOException e) { if (e.getMessage().contains(\"Connection terminated\")) { log.warn(\"client aborted upload\"); return; } throw e; }","preventionTips":["Use resumable uploads for large files","Raise quarkus.http.idle-timeout and proxy timeouts","Avoid client-side request cancellation mid-upload","Verify Content-Length correctness"],"tags":["multipart","network","client-abort"],"backgroundTag":"connection-terminated-mid-upload","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"}