commaai/openpilot · error · ValueError
invalid wrapped firmware checksum
Error message
invalid wrapped firmware checksum
What it means
ValueError from validate_image(): the additive checksum byte at offset body_len+5 does not equal sum(body) & 0xFF. The wrapper stores a simple byte-sum checksum of the firmware body; a mismatch means the body bytes were altered after wrapping - corruption in transfer/storage, or a header length that slices the wrong body window.
Source
Thrown at openpilot/system/hardware/chestnut/flash.py:260
def program(self, addr, data):
self.write_buffer(data + bytes((-len(data)) % 4))
self.write_enable()
self.transaction(0x02, addr, len(data), mode=1)
self.wait_write_done()
def validate_image(data):
if len(data) < 10:
raise ValueError("wrapped firmware is too short")
body_len = int.from_bytes(data[:4], "little")
if body_len > MAX_CODE_SIZE:
raise ValueError(f"wrapped firmware body exceeds {MAX_CODE_SIZE} bytes")
if len(data) != body_len + 10 or data[4 + body_len] != 0xA5:
raise ValueError("invalid wrapped firmware length or magic")
body = data[4:4 + body_len]
if data[5 + body_len] != sum(body) & 0xFF:
raise ValueError("invalid wrapped firmware checksum")
if data[6 + body_len:] != zlib.crc32(body).to_bytes(4, "little"):
raise ValueError("invalid wrapped firmware CRC")
def image_product(image):
match = re.search(rb"custom [0-9a-f]{8}-CLEAN", image)
if match is None:
raise ValueError("no product string in wrapped firmware")
return match.group().decode()
def reconnect(flash):
attempt = 0
while True:
attempt += 1
check_budget()
try:
flash.connect()View on GitHub (pinned to 516ec1e682)
Solutions
- Re-download or re-copy the firmware image in binary mode and re-validate
- Verify transport integrity with sha256 on both ends before flashing
- If building the wrapper yourself, compute the checksum byte as sum(body) & 0xFF after the final body bytes are fixed
- If the checksum is wrong, treat it as corruption - recopy the file; do not patch the checksum byte
Example fix
# after (when wrapping)
checksum = sum(body) & 0xFF
wrapped = struct.pack('<I', len(body)) + body + b'\xa5' + bytes([checksum]) + zlib.crc32(body).to_bytes(4, 'little') Defensive patterns
Strategy: validation
Validate before calling
import struct
def checksum_ok(data: bytes) -> bool:
if len(data) < 10:
return False
body_len = struct.unpack_from('<I', data)[0]
if len(data) != body_len + 10:
return False
return data[5 + body_len] == sum(data[4:4 + body_len]) & 0xFF Prevention
- Checksum artifacts on the build host and re-verify on the flash host before flashing
- Avoid storage media with known bit-rot for firmware artifacts
- Never hand-patch bytes inside a wrapped image
When it happens
Trigger: validate_image(data) where data[5+body_len] != sum(data[4:4+body_len]) & 0xFF. Produced by any corruption in the body, a wrong body_len header (so the checksummed window is wrong), or a file re-encoded in text mode.
Common situations: scp/ftp in ASCII mode flipping bytes; bit rot or partial writes on the target's storage; mixing header and body from different builds when hand-assembling the wrapper; little-endian vs big-endian header mistakes.
Related errors
- invalid wrapped firmware length or magic
- invalid wrapped firmware CRC
- invalid config backup: {backup}
- expected one chestnut, found {len(found)}
- wrapped firmware is too short
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/f06246f9ef6ea0e7.
Report an issue: GitHub.