commaai/openpilot · error · URLFileException
Expected 206 or 200 response {r.status} ({self._url})
Error message
Expected 206 or 200 response {r.status} ({self._url}) What it means
get_multi_range() issues an HTTP Range request and only accepts 200 (server ignored Range, sent everything) or 206 (partial content). Any other status — 403, 404, 416, 500 — raises immediately. 416 usually means seeking past EOF (bad cached length vs. truncated remote file).
Source
Thrown at openpilot/tools/lib/url_file.py:173
if ll is None:
length = self.get_length()
if length == -1:
raise URLFileException(f"Remote file is empty or doesn't exist: {self._url}")
end = length
else:
end = self._pos + ll
data = self.get_multi_range([(self._pos, end)])
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):View on GitHub (pinned to 516ec1e682)
Solutions
- Reproduce with curl -H 'Range: bytes=0-99' <url> to see the actual status
- Reset the URLFile length cache / recreate the URLFile so sizes are re-fetched, then retry
- If the link expired (403), obtain a fresh URL or re-authenticate
Example fix
# before
chunk = uf.get_multi_range([(0, 1024)])
# after
from openpilot.tools.lib.url_file import URLFileException
try:
chunk = uf.get_multi_range([(0, 1024)])
except URLFileException as e:
if '416' in str(e):
uf._length = None # stale cached length
chunk = uf.get_multi_range([(0, 1024)])
else:
raise Defensive patterns
Strategy: try-catch
Try / catch
from openpilot.tools.lib.url_file import URLFileException
try:
parts = uf.get_multi_range(ranges)
except URLFileException as e:
status = str(e).split()[3]
if status == '416':
uf._length = None # stale size: refetch
parts = uf.get_multi_range(ranges)
else:
raise Prevention
- Use fresh URLFile instances after remote files may have changed
- Keep requested ranges within a just-fetched length
- Map the status code to a remedy: 403 expired link, 404 gone, 416 stale size
When it happens
Trigger: Seeking/reading ranges from a URL whose server returns an error for ranged GET: file deleted mid-session, expired link (403), range beyond file size after the file changed, or a server that disallows ranges and errors instead of returning 200.
Common situations: Route file replaced/truncated on the backend while a cached length says it is longer; S3 presigned URL expired; proxy interfering with Range headers.
Related errors
- Failed to {method} {url}: {e}
- Remote file is empty or doesn't exist: {self._url}
- Missing multipart boundary ({self._url})
- Expected {len(ranges)} parts, got {len(parts)} ({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/fa80096639325bcb.
Report an issue: GitHub.