quarkusio/quarkus · error · WebApplicationException

Missing boundary parameter in Content-Type

Error message

Missing boundary parameter in Content-Type

What it means

EntityPartReader.readFrom throws a WebApplicationException when the multipart/form-data Content-Type header has no boundary parameter. RFC 2046 requires a boundary delimiter to delimit multipart parts, so the multipart parser cannot even start without it.

Source

Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/providers/serialisers/EntityPartReader.java:55

        }
        if (mediaType == null || !mediaType.getType().equals("multipart")) {
            return false;
        }
        if (genericType instanceof ParameterizedType pt) {
            Type[] args = pt.getActualTypeArguments();
            return args.length == 1 && args[0] == EntityPart.class;
        }
        return false;
    }

    @Override
    public List<EntityPart> readFrom(Class<List<EntityPart>> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
            throws IOException, WebApplicationException {
        String boundary = mediaType.getParameters().get("boundary");
        if (boundary == null) {
            throw new WebApplicationException("Missing boundary parameter in Content-Type");
        }
        byte[] body = entityStream.readAllBytes();

        List<EntityPart> parts = new ArrayList<>();
        EntityPartCollector collector = new EntityPartCollector(parts);
        MultipartParser.ParseState parser = MultipartParser.beginParse(
                collector, boundary.getBytes(StandardCharsets.US_ASCII), "UTF-8");
        parser.parse(ByteBuffer.wrap(body));
        return parts;
    }

    private static class EntityPartCollector implements MultipartParser.PartHandler {
        private final List<EntityPart> parts;
        private CaseInsensitiveMap<String> currentHeaders;
        private ByteArrayOutputStream currentData;

        EntityPartCollector(List<EntityPart> parts) {
            this.parts = parts;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Let the REST client set the multipart Content-Type itself instead of setting it manually
  2. If setting manually, include the same boundary used in the body: multipart/form-data; boundary=...
  3. Fix proxies/load balancers that rewrite or strip the boundary parameter
  4. Generate the boundary first, build the body with it, then set the header

Example fix

// before
Request req = target.request().header("Content-Type", "multipart/form-data");
// after (let the framework build it, or supply a boundary)
String boundary = "----quarkusBoundary";
Request req = target.request()
    .header("Content-Type", "multipart/form-data; boundary=" + boundary);
Defensive patterns

Strategy: validation

Validate before calling

String contentType = headers.getFirst("Content-Type");
if (contentType == null || !contentType.contains("boundary=")) {
    throw new IllegalStateException("multipart Content-Type must include a boundary parameter");
}

Type guard

boolean hasMultipartBoundary(MediaType mediaType) {
    return mediaType != null && mediaType.getParameters().get("boundary") != null;
}

Try / catch

try {
    List<EntityPart> parts = request.readEntity(new GenericType<List<EntityPart>>() {});
} catch (WebApplicationException e) {
    // respond 400: client sent multipart without boundary
    return Response.status(400, "Missing boundary parameter").build();
}

Prevention

When it happens

Trigger: Sending a request with Content-Type multipart/form-data but omitting the boundary parameter, e.g. manually setting the Content-Type header instead of letting the client generate it, or a server reading a List<EntityPart> from a request whose header lacks boundary.

Common situations: Hand-constructed multipart requests; proxies/gateways stripping Content-Type parameters; clients that set the header before the body is assembled so no boundary exists yet.

Related errors


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