commaai/openpilot · error · ValueError
unknown extension {ext}
Error message
unknown extension {ext} What it means
_LogFileReader derives the compression from the file extension (plus magic-byte fallback). Extensions other than '', '.bz2', '.zst' — e.g. '.gz', '.zip', '.capnp', or a stray suffix — raise ValueError('unknown extension'). This guards against silently misparsing non-log files.
Source
Thrown at openpilot/tools/lib/logreader.py:99
return self._enum
def __getattr__(self, name: str):
if name.startswith("__") and name.endswith("__"):
return getattr(self, name)
return getattr(self._evt, name)
class _LogFileReader:
def __init__(self, fn, only_union_types=False, sort_by_time=False, dat=None):
self.data_version = None
self._only_union_types = only_union_types
ext = None
if not dat:
_, ext = os.path.splitext(urllib.parse.urlparse(fn).path)
if ext not in ('', '.bz2', '.zst'):
# old rlogs weren't compressed
raise ValueError(f"unknown extension {ext}")
with FileReader(fn) as f:
dat = f.read()
if ext == ".bz2" or dat.startswith(b'BZh9'):
dat = bz2.decompress(dat)
elif ext == ".zst" or dat.startswith(b'\x28\xB5\x2F\xFD'):
# https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#zstandard-frames
dat = decompress_stream(dat)
ents = capnp_log.Event.read_multiple_bytes(dat)
self._ents = []
try:
for e in ents:
self._ents.append(CachedEventReader(e))
except capnp.KjException:
warnings.warn("Corrupted events detected", RuntimeWarning, stacklevel=1)View on GitHub (pinned to 516ec1e682)
Solutions
- Use plain, '.bz2', or '.zst' rlog/qlog files — re-compress with `zstd` if needed
- Strip any accidental suffix so the extension is exactly .bz2/.zst or none
- To read in-memory data instead, pass the dat= bytes argument, which bypasses extension checking
Example fix
# before
logs = LogReader('segment/rlog.gz')
# after
import gzip, subprocess
raw = gzip.open('segment/rlog.gz').read()
logs = LogReader(None, dat=subprocess.run(['zstd'], input=raw, capture_output=True).stdout) Defensive patterns
Strategy: validation
Validate before calling
import os, urllib.parse
def valid_log_path(fn: str) -> bool:
ext = os.path.splitext(urllib.parse.urlparse(fn).path)[1]
return ext in ('', '.bz2', '.zst') Try / catch
try:
logs = LogReader(fn)
except ValueError as e:
if 'unknown extension' in str(e):
recompress_to_zst(fn) # then retry Prevention
- Standardize on .zst (current) or .bz2 when archiving logs
- Never gzip rlogs — this reader does not accept .gz
- Pass dat=bytes to bypass extension checks for in-memory data
When it happens
Trigger: Calling LogReader('route/rlog.bz2.x') or a path ending in '.gz'/'.zip'/anything unexpected; also URLs whose path has a query-style suffix that urlparse keeps in the extension.
Common situations: Manually recompressed logs (gzip) instead of zstd/bzip2; passing an index file (.py/.json) to LogReader; rename scripts appending suffixes like '.1' or '.bak'.
Related errors
- Unsupported compression type: {compression}
- Did not find {fn} for seg idxs {needed_seg_idxs} of {sr.rout
- {missing_logs}/{len(sr.seg_idxs)} logs were not found, pleas
- Profile nickname must be 64 bytes or less
- Confirmation code required but not provided
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/39df4f5803ab82f0.
Report an issue: GitHub.