{"record":{"id":"c6181e9089282645","repo":"commaai/openpilot","slug":"failed-to-method-url-e","errorCode":null,"errorMessage":"Failed to {method} {url}: {e}","messagePattern":"Failed to (.+?) (.+?): (.+?)","errorType":"exception","errorClass":"URLFileException","httpStatus":null,"severity":"error","filePath":"openpilot/tools/lib/url_file.py","lineNumber":95,"sourceCode":"    #  Caching enabled by default, can be disabled with DISABLE_FILEREADER_CACHE=1, or overwritten by the cache input\n    self._force_download = int(os.environ.get(\"DISABLE_FILEREADER_CACHE\", \"0\")) == 1\n    if cache is not None:\n      self._force_download = not cache\n\n    if not self._force_download:\n      os.makedirs(Paths.download_cache_root(), exist_ok=True)\n\n  def __enter__(self):\n    return self\n\n  def __exit__(self, exc_type, exc_value, traceback) -> None:\n    pass\n\n  def _request(self, method: str, url: str, headers: dict[str, str] | None = None) -> BaseHTTPResponse:\n    try:\n      return URLFile.pool_manager().request(method, url, timeout=self._timeout, headers=headers)\n    except MaxRetryError as e:\n      raise URLFileException(f\"Failed to {method} {url}: {e}\") from e\n\n  def get_length_online(self) -> int:\n    response = self._request('HEAD', self._url)\n    if not (200 <= response.status <= 299):\n      return -1\n    length = response.headers.get('content-length', 0)\n    return int(length)\n\n  def get_length(self) -> int:\n    if self._length is not None:\n      return self._length\n\n    file_length_path = os.path.join(Paths.download_cache_root(), hash_url(self._url) + \"_length\")\n    if not self._force_download and os.path.exists(file_length_path):\n      with open(file_length_path) as file_length:\n        content = file_length.read()\n        self._length = int(content)\n        return self._length","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/commaai/openpilot/blob/516ec1e68203439a73f340f1d0b3b91eabc626ee/openpilot/tools/lib/url_file.py#L77-L113","documentation":"URLFile._request wraps urllib3's MaxRetryError when an HTTP request to the remote file exhausts retries — DNS failure, connection refused, TLS error, or repeated timeouts. It is openpilot's remote-file layer, so it appears whenever reading a route/segment over HTTP.","triggerScenarios":"Any URLFile/FileReader read on an http(s) path while offline, behind a blocking proxy, with a bad URL, or when the data backend is temporarily down; retries exceeded under flaky Wi-Fi.","commonSituations":"Corporate proxy/VPN rejecting api.comma.ai or cdn hosts; typo'd URL; airplane-mode CI; transient CDN outage.","solutions":["Verify basic connectivity to the exact URL: curl -I <url>","Fix proxy/DNS: set HTTPS_PROXY correctly or disable the VPN, then retry","Add retry-with-backoff around the read, and cache downloaded segments locally so repeated runs don't re-hit the network"],"exampleFix":"# before\ndat = FileReader('https://cdn.../rlog.bz2').read()\n\n# after\nfrom openpilot.tools.lib.url_file import URLFileException\nfor attempt in range(3):\n    try:\n        dat = FileReader('https://cdn.../rlog.bz2').read()\n        break\n    except URLFileException:\n        if attempt == 2: raise\n        time.sleep(2 ** attempt)","handlingStrategy":"retry","validationCode":"import requests\n\ndef url_reachable(url: str) -> bool:\n    try:\n        return requests.head(url, timeout=10).status_code < 500\n    except requests.RequestException:\n        return False","typeGuard":null,"tryCatchPattern":"from openpilot.tools.lib.url_file import URLFileException\nfor attempt in range(3):\n    try:\n        dat = FileReader(url).read()\n        break\n    except URLFileException as e:\n        if attempt == 2 or 'Failed to' not in str(e):\n            raise\n        time.sleep(2 ** attempt)","preventionTips":["Cache downloaded segments locally to avoid repeated network dependency","Check proxy/DNS env (HTTPS_PROXY) in restricted networks","Retry transient network failures with exponential backoff, but never retry 4xx"],"tags":["network","http","url-file","retry"],"backgroundTag":null,"analyzedSha":"516ec1e68203439a73f340f1d0b3b91eabc626ee","analyzedAt":"2026-08-15T00:17:37.461Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}