quarkusio/quarkus · warning · IOException

Connection terminated parsing multipart request

Error message

Connection terminated parsing multipart request

What it means

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.

Source

Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/multipart/MultiPartParserDefinition.java:277

        @Override
        public FormData parseBlocking() throws Exception {
            final FormData existing = exchange.getFormData();
            if (existing != null) {
                return existing;
            }
            try (InputStream inputStream = exchange.getInputStream()) {
                byte[] buf = new byte[1024];
                int c;
                while ((c = inputStream.read(buf)) > 0) {
                    try {
                        parser.parse(ByteBuffer.wrap(buf, 0, c));
                    } catch (MultipartParser.HeaderTooLargeException e) {
                        throw new WebApplicationException(Response.Status.REQUEST_ENTITY_TOO_LARGE);
                    }
                }
                if (!parser.isComplete()) {
                    throw new IOException("Connection terminated parsing multipart request");
                }
                exchange.setFormData(data);
            }
            return data;
        }

        @Override
        public void beginPart(final CaseInsensitiveMap<String> headers) {
            this.currentFileSize = 0;
            this.headers = headers;
            final String disposition = headers.getFirst(HttpHeaders.CONTENT_DISPOSITION);
            if (disposition != null) {
                if (disposition.startsWith("form-data")) {
                    currentName = HeaderUtil.extractQuotedValueFromHeader(disposition, "name");
                    fileName = HeaderUtil.sanitizeFileName(
                            HeaderUtil.extractQuotedValueFromHeaderWithEncoding(disposition, "filename"));
                    String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
                    if (((fileName != null) || isFileContentType(contentType) || fileFormNames.contains(currentName))

View on GitHub (pinned to e1c734241f)

Solutions

  1. Retry the upload from the client with resumable/chunked upload support for large files.
  2. Check client code for early stream close or incorrect Content-Length headers.
  3. Increase proxy/gateway and server timeouts (quarkus.http.idle-timeout) for large uploads.
  4. Handle IOException / client aborts server-side gracefully; log and return a 400 instead of a 500.
Defensive patterns

Strategy: retry

Validate before calling

// client-side: ensure content-length matches body size before sending
long bodySize = computeBodySize(); if (bodySize != declaredLength) throw new IllegalStateException("length mismatch");

Try / catch

try { parseMultipart(exchange); } catch (IOException e) { if (e.getMessage().contains("Connection terminated")) { log.warn("client aborted upload"); return; } throw e; }

Prevention

When it happens

Trigger: 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.

Common situations: Slow mobile clients dropping uploads; proxy/gateway timeouts cutting long uploads; client-side fetch cancellation; broken upload scripts that close the stream early.

Related errors


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