commaai/openpilot · error · URLFileException
Remote file is empty or doesn't exist: {self._url}
Error message
Remote file is empty or doesn't exist: {self._url} What it means
read_aux() with no length argument needs the total file size; get_length() returns -1 when the server's HEAD gives no useful content-length or a non-2xx, and read_aux turns that into 'Remote file is empty or doesn't exist'. So either the URL 404s or the server refuses to report size.
Source
Thrown at openpilot/tools/lib/url_file.py:158
with atomic_write(full_path, mode="wb", overwrite=True) as new_cached_file:
new_cached_file.write(data)
prune_cache(file_name)
else:
with open(full_path, "rb") as cached_file:
data = cached_file.read()
response += data[max(0, file_begin - position): min(CHUNK_SIZE, file_end - position)]
position += CHUNK_SIZE
if position >= file_end:
self._pos = file_end
return response
def read_aux(self, ll: int | None = None) -> bytes:
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:View on GitHub (pinned to 516ec1e682)
Solutions
- curl -I the URL to see the status and Content-Length
- If the link is a presigned URL, regenerate it (they expire)
- Read with an explicit byte length (read(ll)) if the size is known from elsewhere, avoiding the HEAD dependency
Example fix
# before
data = URLFile(url).read()
# after
uf = URLFile(url)
length = uf.get_length_online()
if length <= 0:
raise FileNotFoundError(url)
data = uf.read(length) Defensive patterns
Strategy: validation
Validate before calling
length = URLFile(url).get_length_online()
if length <= 0:
raise FileNotFoundError(url) # or refresh the URL / skip Try / catch
from openpilot.tools.lib.url_file import URLFileException
try:
data = URLFile(url).read()
except URLFileException as e:
if 'empty or doesn' in str(e):
url = refresh_presigned_url(url) # expired link
data = URLFile(url).read() Prevention
- Check content length up front with get_length_online()
- Regenerate presigned URLs rather than storing them long-term
- Read with explicit length when the server's HEAD is unreliable
When it happens
Trigger: URLFile(url).read() (whole-file read) against a URL that returns 404/410, a pre-signed URL that expired, or a server that omits Content-Length on HEAD.
Common situations: Expired/rotated CDN links; route files purged from the backend; mis-pasted URL; servers behind config that strips HEAD handling.
Related errors
- Failed to {method} {url}: {e}
- Expected 206 or 200 response {r.status} ({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/2e3da00361897f56.
Report an issue: GitHub.