commaai/openpilot · critical · Exception
Raw hash mismatch '{raw_hash.hexdigest().lower()}'
Error message
Raw hash mismatch '{raw_hash.hexdigest().lower()}' What it means
After uncompressing and unsparsifying a partition image, verify/flash code compares the SHA-256 of the raw (unsparsified) output against partition['hash_raw']. A mismatch means the bytes written differ from the manifest — corruption in the sparse stream, truncation, or a wrong/man-in-the-middled download.
Source
Thrown at openpilot/common/hardware/comma/agnos.py:176
def extract_compressed_image(target_slot_number: int, partition: dict, cloudlog):
path = get_partition_path(target_slot_number, partition)
downloader = StreamingDecompressor(partition['url'])
with open(path, 'wb+') as out:
# Flash partition
last_p = 0
raw_hash = hashlib.sha256()
f = unsparsify if partition['sparse'] else noop
for chunk in f(downloader):
raw_hash.update(chunk)
out.write(chunk)
p = int(out.tell() / partition['size'] * 100)
if p != last_p:
last_p = p
print(f"Installing {partition['name']}: {p}", flush=True)
if raw_hash.hexdigest().lower() != partition['hash_raw'].lower():
raise Exception(f"Raw hash mismatch '{raw_hash.hexdigest().lower()}'")
if downloader.sha256.hexdigest().lower() != partition['hash'].lower():
raise Exception("Uncompressed hash mismatch")
if out.tell() != partition['size']:
raise Exception("Uncompressed size mismatch")
os.sync()
def flash_partition(target_slot_number: int, partition: dict, cloudlog, standalone=False):
cloudlog.info(f"Downloading and writing {partition['name']}")
if verify_partition(target_slot_number, partition):
cloudlog.info(f"Already flashed {partition['name']}")
return
# Clear hash before flashing in case we get interruptedView on GitHub (pinned to 516ec1e682)
Solutions
- Retry the AGNOS flash — transient corruption is the most common cause
- Check network reliability / use a wired or stable connection for large firmware downloads
- Ensure the manifest and images come from the same release (no partial update)
Defensive patterns
Strategy: retry
Try / catch
for attempt in range(3):
try:
flash_partition(slot, partition, cloudlog)
break
except Exception as e:
if "mismatch" not in str(e):
raise Prevention
- Re-download and re-flash from scratch on any hash mismatch
- Never continue boot after a failed partition flash
When it happens
Trigger: verify_partition()/flash_partition() where the unsparsified output hash differs from the manifest's hash_raw — e.g. a chunk was dropped or reordered by the streaming decompressor.
Common situations: Corrupted download over flaky network; partial write after power loss; manifest and image versions out of sync.
Related errors
- Unhandled sparse chunk type
- Uncompressed hash mismatch
- Uncompressed size mismatch
- Maximum retries exceeded
- flash did not converge within {FLASH_BUDGET:g}s
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/06a78dfe2425bdd0.
Report an issue: GitHub.