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
- 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]
- Inspect the raw header with curl -v and confirm what the server actually sends
- 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
- Issue one range per request for maximum server compatibility
- Avoid multi-range reads through proxies you don't control
- Log the raw content-type header when debugging range behavior
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
- Expected {len(ranges)} parts, got {len(parts)} ({self._url})
- Failed to {method} {url}: {e}
- Remote file is empty or doesn't exist: {self._url}
- Expected 206 or 200 response {r.status} ({self._url})
- {error_prefix} failed: {reason}/{subject} - {sd.get('message
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/eb4bbd562da429d3.
Report an issue: GitHub.