reflex-dev/reflex · error · MultiPartException

Missing boundary in multipart.

Error message

Missing boundary in multipart.

What it means

The streaming multipart parser requires a boundary parameter in the request's Content-Type header to split parts. Missing boundary raises MultiPartException chained from a KeyError when reading params[b"boundary"].

Source

Thrown at packages/reflex-components-core/src/reflex_components_core/core/_upload.py:473

    async def parse(self) -> None:
        """Parse the incoming request stream and push chunks to the iterator.

        Raises:
            MultiPartException: If the request is not valid multipart upload data.
            RuntimeError: If the upload handler exits before consuming all chunks.
            HTTPException: If the bound-args field is not a valid JSON object.
        """
        _, params = parse_options_header(self.headers["Content-Type"])
        charset = params.get(b"charset", "utf-8")
        if isinstance(charset, bytes):
            charset = charset.decode("latin-1")
        self._charset = charset

        try:
            boundary = params[b"boundary"]
        except KeyError as err:
            msg = "Missing boundary in multipart."
            raise MultiPartException(msg) from err

        callbacks = {
            "on_part_begin": self.on_part_begin,
            "on_part_data": self.on_part_data,
            "on_part_end": self.on_part_end,
            "on_header_field": self.on_header_field,
            "on_header_value": self.on_header_value,
            "on_header_end": self.on_header_end,
            "on_headers_finished": self.on_headers_finished,
            "on_end": self.on_end,
        }
        parser = MultipartParser(boundary, cast(Any, callbacks))

        async for chunk in self.stream:
            self._stream_chunk_count += 1
            parser.write(chunk)
            await self._maybe_start_handler()
            await self._flush_emitted_chunks()

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Don't set Content-Type manually in fetch — pass FormData and let the browser add the boundary
  2. Check proxy/gateway config for header rewriting on the upload route
  3. In tests, use files=/data= parameters of HTTP clients so the boundary is generated

Example fix

// before
fetch(url, {method:'POST', headers:{'Content-Type':'multipart/form-data'}, body: formData})

// after
fetch(url, {method:'POST', body: formData})  // browser sets boundary
Defensive patterns

Strategy: validation

Validate before calling

ctype = request.headers.get("content-type", "")
assert "boundary=" in ctype, f"bad content-type: {ctype}"

Prevention

When it happens

Trigger: A POST to the upload endpoint with Content-Type: multipart/form-data but no ; boundary=... parameter — e.g. manually set headers, stripped by a proxy, or a plain urlencoded body hitting the multipart route.

Common situations: fetch() with manually set Content-Type instead of letting the browser set it with the boundary; reverse proxies (nginx) stripping or rewriting the header; API gateways re-encoding bodies; unit tests posting raw bodies.

Related errors


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/2937d340100608b4. Report an issue: GitHub.