Technology · PRACTICAL GUIDE
Git reports a corrupt pack or index-pack failure? Prove which boundary lost bytes first
Separate a damaged local object database from a truncated transfer and a server-side pack failure before moving packs, recloning, or running garbage collection.

A pack checksum mismatch and an invalid index-pack output do not name the same owner. One can describe stored repository damage; the other can be the last visible symptom of a truncated transfer or failed remote pack producer.
Do not begin by deleting packs, recloning over the only worktree, or running gc. Preserve the first error and object database, prove the boundary, recover from a known-good source, then close on objects, refs, working changes and a repeatable transfer.
Preserve the first failure and freeze object mutation
Save the complete command, Git version, repository path, stderr, exit status, transport, remote URL with credentials removed, and the first checksum, CRC, bad-offset, early-EOF, or index-pack line. Stop automatic gc, repack, prune, fetch, mirror and backup jobs until the evidence is copied.
Make a filesystem-level copy of the repository and separately preserve uncommitted working-tree and index changes. Do not test recovery on the only copy. Record the hashes, sizes and names of every implicated .pack and .idx file before moving, deleting, regenerating or recloning anything.
Decide whether the failure is local, in transit, or remote
A stored local pack checksum or CRC failure points to the receiving object database. Early EOF plus invalid index-pack output during clone can instead mean truncated transport, exhausted client storage, proxy or SSH failure, or a remote pack-objects failure. Preserve server logs when you control the producer.
Compare one unaffected client, one clean destination, and—when approved—one alternate transport. A failure limited to one existing clone differs from every fresh clone of one repository; a failure across all repositories on one client differs again. Do not change global buffers or compression merely because a community answer lists them.
Map the exact pack, index, objects and refs
Run git fsck --full on the preserved copy and save its output. Use git verify-pack on the exact .idx/.pack pair named by the evidence; verbose output can map object IDs and offsets. If the index alone is suspect, index-pack can build an index for a copied pack, but success does not prove every required ref is reachable.
Separate a pack checksum mismatch, an index checksum or CRC mismatch, a bad object at an offset, a missing referenced object, and a dangling but unreferenced object. Record which refs and commits require each missing object. Connectivity-only checks deliberately avoid reading blob contents, so they are not a substitute for a full integrity run.
Recover from a known-good source with the narrowest change
If the local clone is disposable and an independently verified remote contains every required ref, create a new clone in another directory, preserve local changes, and compare exact commit IDs before retiring the damaged copy. If the remote or server repository is damaged, use a verified backup or another known-good clone as the object source.
Restore only the exact missing objects or verified pack material under an authorized recovery plan, with correct ownership and permissions. Pack salvage and unpack-objects belong on a copy and may recover only readable objects; they are not permission to delete the damaged original or run gc/prune against incomplete evidence.
Close on integrity, refs, work and repeatability
Run a final full fsck and verify the intended branches, tags and exact commit IDs against the source of truth. Confirm that preserved uncommitted work is represented separately and that critical commits, trees and blobs can be read. A successful checkout of one branch does not prove every required object survived.
Repeat the original clone or fetch on the repaired boundary into a new empty destination and preserve its log. Close only when integrity is clean for the required scope, refs match, working changes are accounted for, and the transfer no longer truncates or regenerates corrupt bytes.
