Why source archive hashes suddenly changed

On January 30, 2023, GitHub deployed Git 2.38 to the service that powers source code downloads, and that update had an unintended ripple effect. The new Git version changed the default compression command used by git archive from external gzip to an internal copy of gzip. Although the actual file contents inside the archives were identical, the byte layout of the generated tarballs and zipballs shifted slightly due to different compression settings. For any community that records a hash or checksum of a downloaded archive, that meant the previously recorded SHA256, CRC64, or other digest no longer matched, causing clients to refuse downloads under the assumption of tampering or corruption.

GitHub does not store git archive results permanently. Given the volume of data it handles, archives are cached, then deleted and regenerated on demand. That storage strategy balances availability of releases, tags, and arbitrary commits against unsustainable storage growth. When a cached archive was recreated after the Git upgrade, it came back with the new byte layout, and downstream systems that compare hashes against centrally recorded values started failing.

Known risk, unexpected blast radius

GitHub says it was aware of the upstream change in git archive defaults but underestimated how widely communities relied on byte-for-byte stability of downloads. Internally, the company says it never guaranteed that stability, since the Git project itself makes no such promise and GitHub aims to keep its fork of Git as close to upstream as possible rather than carrying permanent patches. The incident made clear that this position was not always communicated effectively to users.

New stability commitment

GitHub has now committed to an explicit policy for source download archives:

  • Source downloads — both .tar.gz tarballs and .zip zipballs — will remain byte-for-byte stable for no less than one year from February 21, 2023.
  • Any future change to either archive format will be announced with six months' notice in documentation, the GitHub blog, and the changelog. The notice period may be shortened or waived only in the event of a critical vulnerability in the compression path.
  • There is presently no intent to change either format. Known deficiencies — embedded timestamps in zipballs and the dependency on system gzip for tarballs — will be engineered around for the foreseeable future.

GitHub is also adding testing to its development cycle to detect future changes in archive output before they reach the production service.

Recommendations for affected projects

If your goal is reproducibility — ensuring identical file contents every time — GitHub recommends downloading source archives via the source archives REST API using a commit ID for the :ref parameter. Since commit IDs deterministically map to file contents, there is no need to record a separate hash; the commit ID already guarantees the same files. This approach is also immune to rewritten tags or moved branch heads. Tarball and zipball formats have built-in truncation protections, and HTTPS provides integrity during transfer.

If you rely on archive stability for security — for example, to prevent accidental extraction of a tarbomb — GitHub suggests switching to release assets instead of source downloads. These are the files uploaded to a release page and displayed with their sizes, either added manually via the web UI or through tools like this third-party GitHub Action. Release assets can be retrieved through the Release Assets REST API. If that migration is not feasible, designs should accommodate occasional future hash changes.