commaai/openpilot · critical · Exception
Uncompressed hash mismatch
Error message
Uncompressed hash mismatch
What it means
The compressed bytes received from the downloader are hashed (downloader.sha256) and compared against partition['hash']. A mismatch means the compressed stream itself is corrupted even before decompression — network corruption, proxy mangling, or a stale/cached partial file.
Source
Thrown at openpilot/common/hardware/comma/agnos.py:179
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 interrupted
full_check = partition['full_check']
if not full_check:
clear_partition_hash(target_slot_number, partition)View on GitHub (pinned to 516ec1e682)
Solutions
- Retry the download (the retry loop already handles RequestException; hash mismatch should be retried too)
- Verify the manifest URL and hash are from the same AGNOS release
- Rule out intercepting proxies or modified TLS appliances on the network
Defensive patterns
Strategy: retry
Try / catch
# extend the existing retry loop to catch hash mismatches, not just RequestException
except (requests.exceptions.RequestException, Exception) as e:
if 'hash mismatch' not in str(e):
raise
time.sleep(10) Prevention
- Ensure manifest and images come from the same release
- Avoid intercepting proxies on the firmware download network
When it happens
Trigger: flash_partition where the downloaded (still-compressed) stream hash differs from the manifest hash — truncated HTTP response, corrupt gzip/bzip stream, or wrong URL.
Common situations: Flaky Wi-Fi during multi-hundred-MB firmware download; interrupted resume serving partial content; CDN/cache serving a corrupted artifact.
Related errors
- Raw hash mismatch '{raw_hash.hexdigest().lower()}'
- Unhandled sparse chunk type
- Uncompressed size mismatch
- Maximum retries exceeded
- AuthenticateServer rejected by eUICC: {AUTH_SERVER_ERROR_COD
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/85ee94d68ce3cd84.
Report an issue: GitHub.