commaai/openpilot · error · ValueError

wrapped firmware is too short

Error message

wrapped firmware is too short

What it means

ValueError from validate_image(): the wrapped firmware file passed for flashing is under 10 bytes total. A valid wrapper is a 4-byte little-endian body length + body + magic byte + checksum byte + 4-byte CRC32, so it can never be shorter than 10 bytes. A file this small is essentially empty, truncated, or the wrong file entirely.

Source

Thrown at openpilot/system/hardware/chestnut/flash.py:252

      for off in range(0, n, 255):
        out += self.reg_read(0x7000 + off, min(255, n - off))
    return bytes(out)

  def erase_sector(self, addr):
    self.write_enable()
    self.transaction(0x20, addr)
    self.wait_write_done()

  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()

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Check the file with ls -l and file on firmware_wrapped.bin - a real image is roughly 65KB (up to 0x10000 body + 10 bytes wrapper)
  2. Regenerate or re-download the firmware artifact from the build that produces it (the wrapper is created by the packaging step, not hand-made)
  3. If supplying your own image, re-export it; do not hand-edit binaries
  4. Verify the path you pass actually points at the wrapped bin, not an unrelated file
Defensive patterns

Strategy: validation

Validate before calling

import os

def image_plausible(path) -> bool:
    size = os.path.getsize(path)
    return 10 <= size <= 10 + 0x10000

Prevention

When it happens

Trigger: validate_image(data) where data came from FIRMWARE_PATH (firmware_wrapped.bin next to the script) or a user-supplied image: the file is 0-9 bytes - empty placeholder, a failed download, a git-LFS pointer stub, or a text file passed by mistake.

Common situations: firmware_wrapped.bin missing from the deployment with an empty file left in its place; a truncated artifact from an interrupted CI download; pointing --image at a README or checksum file instead of the wrapped binary.

Related errors


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