Skip to content

verify

zpack verify <archive.zpak>

Reads and rehashes every entry, reporting the first mismatch:

Terminal window
$ zpack verify game.zpak
Verified 56 entries

Nothing is written to disk. This is the check to run in CI, after a download, or before shipping a build.

  1. The index, in full - every offset, size, path, and method, exactly as open does
  2. Every entry’s contents, decompressed and hashed, against the hash field recorded when it was packed
  3. Every entry’s length - an entry that produces more or fewer bytes than the index promised fails, even if the prefix hashed correctly

That third check is what bounds decompression. The index states each entry’s original size up front, so verify reads one byte past it and stops. A deflate stream that keeps producing bytes is reported as a length mismatch rather than being read to exhaustion.

The hash is XxHash64, chosen to detect accidental corruption - a flipped bit, a truncated download, a failing disk. It is not a MAC. Anyone able to modify an archive can recompute the hashes to match, so verify says nothing about whether an archive came from who you think it did. See the security model.

verify reads the entire archive and decompresses every deflated entry, so it costs roughly what unpack costs minus the writes. Memory stays flat: entries stream through a single reused buffer rather than being held whole.

Terminal window
$ zpack verify damaged.zpak
zpack: 'damaged.zpak' failed verification: HashMismatch
$ zpack verify truncated.zpak
zpack: cannot open archive 'truncated.zpak': CorruptArchive

A structural problem is caught when the archive is opened, and reported as cannot open archive. A contents problem is caught during the pass, and reported as failed verification. The first mismatch stops the command; it does not report every bad entry.