commaai/openpilot · error · DataUnreadableError

Failed to index

Error message

Failed to index {fn!r}

What it means

get_index_data() requires a video index; if get_video_index(fn) returns None (no cached index and indexing produced nothing usable), it raises DataUnreadableError('Failed to index ...'). In practice get_video_index rarely returns None — assert_hvec/ffprobe usually raise earlier — so this is the catch-all when indexing silently yields nothing, e.g. via the cached path.

Solutions

  1. Delete the framereader index cache for that route and retry so it is rebuilt
  2. Validate the file directly: ffprobe and hevc_index on the same path to see which stage yields nothing
  3. If it reproduces, the camera file itself is bad — re-download or use another segment

Example fix

# before
index, prefix, w, h = get_index_data(fn)

# after
from openpilot.tools.lib.framereader import get_index_data, DataUnreadableError
try:
    index, prefix, w, h = get_index_data(fn)
except DataUnreadableError:
    cache_clear_for(fn)  # or: os.remove(index_cache_path(fn))
    index, prefix, w, h = get_index_data(fn)
Defensive patterns

Strategy: fallback

Try / catch

from openpilot.tools.lib.exceptions import DataUnreadableError
try:
    index, prefix, w, h = get_index_data(fn)
except DataUnreadableError:
    clear_framereader_cache(fn)
    index, prefix, w, h = get_index_data(fn)  # one rebuild attempt

Prevention

When it happens

Trigger: Calling FrameReader/get_index_data on a file that passes the header check but produces no index — typically an index-cache miss combined with a degenerate stream, or when index_data passed in as None and the underlying file became unreadable between calls.

Common situations: Corrupted .idx/cache files produced by a previous partial run; race between concurrent processes writing the video index cache.

Related errors


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

Appendix: source

Thrown at openpilot/tools/lib/framereader.py:87

def ffprobe(fn, fmt=None):
  fn = resolve_name(fn)
  cmd = ["ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams"]
  if fmt:
    cmd += ["-f", fmt]
  cmd += ["-i", "pipe:0"]

  try:
    with FileReader(fn) as f:
      ffprobe_output = subprocess.check_output(cmd, input=f.read(4096))
  except subprocess.CalledProcessError as e:
    raise DataUnreadableError(fn) from e
  return json.loads(ffprobe_output)

def get_index_data(fn: str, index_data: dict|None = None):
  if index_data is None:
    index_data = get_video_index(fn)
    if index_data is None:
      raise DataUnreadableError(f"Failed to index {fn!r}")
  stream = index_data["probe"]["streams"][0]
  return index_data["index"], index_data["global_prefix"], stream["width"], stream["height"]

def get_video_index(fn):
  assert_hvec(fn)
  frame_types, dat_len, prefix = hevc_index(fn)
  index = np.array(frame_types + [(0xFFFFFFFF, dat_len)], dtype=np.uint32)
  probe = ffprobe(fn, "hevc")
  return {
    'index': index,
    'global_prefix': prefix,
    'probe': probe
  }

class FfmpegDecoder:
  def __init__(self, fn: str, index_data: dict|None = None,
               pix_fmt: str = "rgb24", hwaccel="auto", loglevel="quiet"):
    self.fn = fn

View on GitHub (pinned to 516ec1e682)