commaai/openpilot · error · URLFileException

Missing multipart boundary ({self._url})

Error message

Missing multipart boundary ({self._url})

What it means

When a multi-range response's Content-Type is multipart/byteranges, url_file must split parts by the boundary parameter in that header. If 'boundary=' is missing (or unparseable by its regex), it cannot split and raises. Malformed server/proxy responses cause this; compliant servers always include it.

Source

Thrown at openpilot/tools/lib/url_file.py:181

    self._pos += len(data[0])
    return data[0]

  def get_multi_range(self, ranges: list[tuple[int, int]]) -> list[bytes]:
    # HTTP range requests are inclusive
    assert all(e > s for s, e in ranges), "Range end must be greater than start"
    rs = [f"{s}-{e-1}" for s, e in ranges if e > s]

    r = self._request("GET", self._url, headers={"Range": "bytes=" + ",".join(rs)})
    if r.status not in [200, 206]:
      raise URLFileException(f"Expected 206 or 200 response {r.status} ({self._url})")

    ctype = (r.headers.get("content-type") or "").lower()
    if "multipart/byteranges" not in ctype:
      return [r.data,]

    m = re.search(r'boundary="?([^";]+)"?', ctype)
    if not m:
      raise URLFileException(f"Missing multipart boundary ({self._url})")
    boundary = m.group(1).encode()

    parts = []
    for chunk in r.data.split(b"--" + boundary):
      if b"\r\n\r\n" not in chunk:
        continue
      payload = chunk.split(b"\r\n\r\n", 1)[1].rstrip(b"\r\n")
      if payload and payload != b"--":
        parts.append(payload)
    if len(parts) != len(ranges):
      raise URLFileException(f"Expected {len(ranges)} parts, got {len(parts)} ({self._url})")
    return parts

  def seekable(self) -> bool:
    return True

  def seek(self, pos: int, whence: int = 0) -> int:
    pos = int(pos)

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Issue single ranges instead (one range per request) so the response is never multipart: [uf.get_multi_range([(s, e)])[0] for s, e in ranges]
  2. Inspect the raw header with curl -v and confirm what the server actually sends
  3. If you control the server, always emit 'Content-Type: multipart/byteranges; boundary=...'

Example fix

# before
parts = uf.get_multi_range(ranges)

# after
parts = [uf.get_multi_range([r])[0] for r in ranges]  # one range per request: no multipart parsing
Defensive patterns

Strategy: fallback

Try / catch

try:
    parts = uf.get_multi_range(ranges)
except URLFileException as e:
    if 'multipart boundary' in str(e):
        parts = [uf.get_multi_range([r])[0] for r in ranges]  # single-range requests

Prevention

When it happens

Trigger: get_multi_range() with multiple ranges against a server/proxy that sends multipart/byteranges but omits the boundary parameter, or formats it unusually (e.g. boundary without '=' in a form the regex misses).

Common situations: Intermediate proxies (corporate proxies, some CDNs) rewriting responses; custom or self-hosted file servers with sloppy header generation.

Related errors


AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15). Data as JSON: /api/errors/eb4bbd562da429d3. Report an issue: GitHub.