Overview
The error fatal: packfile is corrupt means a Git pack (the file that stores many objects efficiently) failed checksum or index validation. Common causes:
- Interrupted writes or power loss during pack updates
- Disk or filesystem errors
- Bad download/caching over HTTP(S)
- Antivirus or backup tools locking or truncating .git files
This guide shows fast, practical fixes for both local clones and server/bare repositories.
Quickstart (local repo with a healthy remote)
- Verify corruption and find the bad file
# From the repository root
git fsck --full
# Note the failing path, e.g. .git/objects/pack/pack-xxxxxx.pack or .idx
- Quarantine the corrupted pack and its index
mkdir -p .git/objects/pack/bad
for f in .git/objects/pack/pack-*.{pack,idx}; do
if ! git verify-pack -v "$f" >/dev/null 2>&1; then
mv "$f" .git/objects/pack/bad/
fi
done
- Re-download missing objects from the remote
git fetch --all --prune --force
- Rebuild packs and clean up
git gc --prune=now
- Re-verify
git fsck --full
If fsck returns clean, resume work.
Minimal working example (simulate and repair)
This example creates a tiny origin, corrupts a clone’s pack, then repairs it.
set -euo pipefail
# 1) Create a small origin
rm -rf /tmp/origin.git /tmp/work
mkdir -p /tmp/origin && cd /tmp/origin
git init --bare ./origin.git
# 2) Make a repo with a couple of commits and push
mkdir /tmp/src && cd /tmp/src
git init
printf 'hello\n' > hello.txt
git add hello.txt && git commit -m "init"
printf 'world\n' >> hello.txt
git commit -am "update"
git remote add origin /tmp/origin/origin.git
git push -u origin HEAD:main
# 3) Clone and force a pack
cd /tmp
git clone /tmp/origin/origin.git work
cd work
git gc # ensures a pack exists
# 4) Corrupt the first pack by appending a byte
pack=$(ls .git/objects/pack/pack-*.pack | head -n1)
printf '\0' >> "$pack"
# 5) Observe the error
set +e
git fsck --full || true
set -e
# 6) Repair: quarantine, refetch, gc
mkdir -p .git/objects/pack/bad
mv "$pack" "${pack%.pack}.idx" .git/objects/pack/bad/ || true
git fetch --all --prune --force
git gc --prune=now
git fsck --full
Expected: The first fsck reports corruption; after the repair steps, fsck is clean.
Fixes by scenario
| Scenario | Recommended actions |
|---|---|
| Local clone, healthy remote | Quarantine bad .pack/.idx; git fetch --all --prune --force; git gc; git fsck |
| Local clone, no remote/backup | If only .idx corrupt: rebuild with git index-pack; if .pack corrupt: try git fsck --lost-found, otherwise restore from another clone/backup |
| Server/bare repo | Run git fsck; git gc or git repack -Ad; if clients still fail, remove corrupt packs, then repack and advertise refs |
| HTTP(S) fetch issues | Retry fetch; disable intermediaries caching .pack; ensure complete redownload (git fetch --prune --force) |
| Shallow clone | git fetch --unshallow or increase depth, then gc |
| Git LFS | git lfs fetch --all; git lfs fsck; git lfs prune |
Detailed procedures
Rebuild a corrupt pack index (.idx) only
If fsck or verify-pack indicates only the .idx is wrong and the .pack is intact:
pack=.git/objects/pack/pack-xxxxxxxxxxxxxxx.pack
# Rebuild index for that pack
git index-pack -v "$pack"
# or explicitly write the index path
# git index-pack -v -o "${pack%.pack}.idx" "$pack"
Re-run git fsck.
Salvage without a remote
If the .pack is corrupt and no healthy remote exists:
- Try to recover loose/dangling objects:
git fsck --lost-found
# Inspect .git/lost-found/ for blobs/trees you can manually reattach
- Check other machines/clones and clone from a healthy copy.
- Restore from backups or snapshots.
Server/bare repository maintenance
Run these on the server hosting a bare repo to repair and optimize:
# Inspect
git fsck --full
# Conservative cleanup and repacking
git gc # safe default; repacks and prunes unreachable objects
# If problems persist, force a full repack and remove old packs
git repack -Ad
# Optional: write bitmap index to speed clones and fetches
git repack -Ad --write-bitmap-index
git fsck --full
If a specific pack is known bad, move it aside before repacking, then fetch from the server again from clients.
Network transport issues
Intermittent corruption during fetch usually indicates a bad cache/proxy or truncated downloads. Remedies:
- Re-fetch with force to redownload packs: git fetch --all --prune --force
- Bypass or disable HTTP caching layers for .pack/.idx paths
- Retry over SSH instead of HTTP(S) to isolate transport
Pitfalls
- Deleting packs without a healthy remote or backup can permanently lose commits.
- git gc --prune=now removes unreachable objects immediately; avoid on servers until you confirm no refs rely on them.
- Antivirus/backup tools that scan inside .git can corrupt or lock files; exclude .git directories.
- Don’t run aggressive repacks during peak hours; high I/O and CPU can stall CI.
Performance notes
- git gc is usually sufficient; git gc --aggressive improves compression but is CPU-heavy and slow on large repos.
- For servers, prefer targeted repacks: git repack -Ad --write-bitmap-index to speed clones/fetches.
- Schedule periodic maintenance:
# Enable background maintenance (Git >= 2.30)
git maintenance start
# Or run on demand
git maintenance run --task=gc
- Large repos: ensure ample disk space for temporary packs (often 2–3x repo size during repack).
- Verify disk health (SMART) if corruption recurs; packfiles stress I/O.
Prevention checklist
- Stable storage: UPS, reliable disks, exclude .git from aggressive scanners.
- Regular integrity checks on servers: git fsck --full via cron.
- Routine maintenance: git gc or git maintenance.
- Avoid abrupt shutdowns during clone/fetch/push.
- Keep multiple clones/backups for recovery.
FAQ
What causes packfile corruption?
- Interrupted writes, disk errors, or incomplete downloads. Less commonly, RAM or filesystem issues.
Is my data lost?
- If you have a healthy remote or another clone, you can redownload. Without that, recovery depends on fsck --lost-found or backups.
What’s the difference between .pack and .idx?
- .pack stores objects; .idx maps object IDs to offsets in the pack. A bad .idx is often fixable; a bad .pack may require refetch or restore.
Should I run --aggressive?
- Only if you need maximal compression and can afford the time. It doesn’t fix corruption better than a normal gc.
Does re-cloning help?
- Yes, if the remote is healthy. For persistent server-side issues, repair the bare repo first (gc/repack, then fsck).