commaai/openpilot · error · LogsUnavailable

{missing_logs}/{len(sr.seg_idxs)} logs were not found, pleas

Error message

{missing_logs}/{len(sr.seg_idxs)} logs were not found, please ensure all logs are uploaded. You can fall back to qlogs with '/a' selector at the end of the route name.

Exceptions for sources:
  - {exceptions joined with \n  - }

What it means

The terminal failure of LogReader's source-resolution loop: after trying every source for both rlogs and qlogs (and any interactive/automatic fallback declined or exhausted), the remaining missing segments raise LogsUnavailable with a per-source exception summary. It means the requested logs genuinely could not be fetched from anywhere.

Source

Thrown at openpilot/tools/lib/logreader.py:198

        # We've found all files, return them
        if len(needed_seg_idxs) == 0:
          return list(valid_files.values())
        else:
          raise FileNotFoundError(f"Did not find {fn} for seg idxs {needed_seg_idxs} of {sr.route_name}")

      except Exception as e:
        exceptions[source.__name__] = e

    if fn == try_fns[0]:
      missing_logs = len(needed_seg_idxs)
      if mode == ReadMode.AUTO:
        cloudlog.warning(f"{missing_logs}/{len(sr.seg_idxs)} rlogs were not found, falling back to qlogs for those segments...")
      elif mode == ReadMode.AUTO_INTERACTIVE:
        if input(f"{missing_logs}/{len(sr.seg_idxs)} rlogs were not found, would you like to fallback to qlogs for those segments? (y/N) ").lower() != "y":
          break

  missing_logs = len(needed_seg_idxs)
  raise LogsUnavailable(f"{missing_logs}/{len(sr.seg_idxs)} logs were not found, please ensure all logs " +
                        "are uploaded. You can fall back to qlogs with '/a' selector at the end of the route name.\n\n" +
                        "Exceptions for sources:\n  - " + "\n  - ".join([f"{k}: {repr(v)}" for k, v in exceptions.items()]))


def parse_indirect(identifier: str) -> str:
  if "useradmin.comma.ai" in identifier:
    query = parse_qs(urlparse(identifier).query)
    identifier = query["onebox"][0]
  elif "connect.comma.ai" in identifier:
    path = urlparse(identifier).path.strip("/").split("/")
    path = ['/'.join(path[:2]), *path[2:]]  # recombine log id

    identifier = path[0]
    if len(path) > 2:
      # convert url with seconds to segments
      start, end = int(path[1]) // 60, int(path[2]) // 60 + 1
      identifier = f"{identifier}/{start}:{end}"

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Read the per-source exceptions in the message — they name the real cause (401/404/URL errors)
  2. Verify route accessibility: open it in cabana/connect, or check `api.get('/v1/route/...')`
  3. If rlogs are known-missing, request qlogs up front with the '/a' selector instead of declining the fallback

Example fix

# before
logs = LogReader(route_name)

# after
from openpilot.tools.lib.logreader import LogsUnavailable
try:
    logs = LogReader(route_name)
except LogsUnavailable:
    logs = LogReader(route_name + '/a')  # qlog fallback
Defensive patterns

Strategy: fallback

Try / catch

from openpilot.tools.lib.logreader import LogsUnavailable
try:
    logs = LogReader(route_name)
except LogsUnavailable as e:
    # message lists per-source exceptions; inspect before giving up
    raise SystemExit(f'route unavailable: {e}')

Prevention

When it happens

Trigger: LogReader/SimpleLogReader on a route where rlogs are missing AND the qlog fallback was declined (answered 'n' in AUTO_INTERACTIVE) or qlogs are also missing; fully un-uploaded routes.

Common situations: Route never uploaded (only on device); auth token lacking access to a private route; typo'd dongle ID/route timestamp so nothing matches; data still syncing.

Related errors


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