commaai/openpilot · critical · Exception
Unhandled sparse chunk type
Error message
Unhandled sparse chunk type
What it means
unsparsify() walks Android sparse-image chunks and only understands types 0xcac1 (raw), 0xcac2 (fill), and 0xcac3 (don't-care). Any other chunk type in the header raises this generic Exception, meaning the downloaded image is not a sparse image this parser supports (or is corrupt).
Source
Thrown at openpilot/common/hardware/comma/agnos.py:85
block_sz = struct.unpack("I", f.read(4))[0]
f.read(4) # total blocks
num_chunks = struct.unpack("I", f.read(4))[0]
f.read(4) # crc checksum
for _ in range(num_chunks):
chunk_type, out_blocks = SPARSE_CHUNK_FMT.unpack(f.read(12))
if chunk_type == 0xcac1: # Raw
# TODO: yield in smaller chunks. Yielding only block_sz is too slow. Largest observed data chunk is 252 MB.
yield f.read(out_blocks * block_sz)
elif chunk_type == 0xcac2: # Fill
filler = f.read(4) * (block_sz // 4)
for _ in range(out_blocks):
yield filler
elif chunk_type == 0xcac3: # Don't care
yield b""
else:
raise Exception("Unhandled sparse chunk type")
# noop wrapper with same API as unsparsify() for non sparse images
def noop(f: StreamingDecompressor) -> Generator[bytes, None, None]:
while len(chunk := f.read(1024 * 1024)) > 0:
yield chunk
def get_target_slot_number() -> int:
current_slot = subprocess.check_output(["abctl", "--boot_slot"], encoding='utf-8').strip()
return 1 if current_slot == "_a" else 0
def slot_number_to_suffix(slot_number: int) -> str:
assert slot_number in (0, 1)
return '_a' if slot_number == 0 else '_b'
View on GitHub (pinned to 516ec1e682)
Solutions
- Retry the AGNOS update — the image stream is likely corrupted in transit
- Verify the manifest hash matches the image being downloaded
- Confirm the image is an Android sparse image compatible with this parser
Defensive patterns
Strategy: retry
Try / catch
try:
flash_agnos_update(manifest)
except Exception as e:
if "Unhandled sparse chunk type" in str(e):
clear_download_cache_and_retry() Prevention
- Verify firmware image hashes before flashing
- Use a reliable network for firmware downloads
When it happens
Trigger: Flashing an AGNOS partition whose streamed image contains a chunk header with an unexpected type value — corrupt download, wrong image, or a new sparse format variant.
Common situations: Truncated/corrupted firmware download producing garbage chunk headers; flashing a non-sparse or newer-format image through the sparse path; endianness/sign issues in a hand-built image.
Related errors
- Raw hash mismatch '{raw_hash.hexdigest().lower()}'
- Uncompressed size mismatch
- Uncompressed hash 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/a1fd9bccebbc7692.
Report an issue: GitHub.