KhueApps
Home/DevOps/Fixing Git error: fatal: pack has bad object

Fixing Git error: fatal: pack has bad object

Last updated: October 07, 2025

What this error means

“fatal: pack has bad object” indicates a corrupted pack file in .git/objects/pack. Git cannot read one or more objects, breaking operations like fetch, log, or checkout.

Common causes:

  • Interrupted fetch/clone or power loss while writing packs
  • Disk or filesystem errors
  • Antivirus/sync tools locking or modifying .pack/.idx
  • Broken alternates or partial/shallow clones

Quickstart (safe defaults)

If you have no unpushed work, recloning is fastest. If you do, follow:

# 1) Back up your working tree (protect uncommitted files)
rsync -a --exclude='.git' . ../repo-backup-$(date +%s)/

# 2) Identify corrupt packs
git fsck --full --strict || true

# 3) Move suspected pack(s) out of the way; re-fetch clean objects
mkdir -p .git/objects/pack/quarantine
for p in .git/objects/pack/pack-*.pack; do
  git verify-pack -v "$p" >/dev/null 2>&1 || mv "$p" "${p/.pack/.idx}" .git/objects/pack/quarantine/ 2>/dev/null || true
  # Move idx too if present
  [ -f "${p%.pack}.idx" ] && mv "${p%.pack}.idx" .git/objects/pack/quarantine/ || true
done

# 4) Re-download objects
git fetch --all --prune --force --tags

# 5) Repack and clean
git repack -Ad -l
git gc --prune=now

# 6) Verify
git fsck --full --strict

If fsck still fails, consider a fresh clone and cherry-pick local changes from your backup directory.

Minimal working example (reproduce and fix)

This demo corrupts a disposable repo, triggers the error, then fixes it.

set -euo pipefail

# Create a bare remote and a working clone
rm -rf /tmp/git-pack-demo
mkdir -p /tmp/git-pack-demo
cd /tmp/git-pack-demo

git init --bare remote.git

git clone remote.git work
cd work
echo hello > file.txt
git add file.txt
git commit -m "init"
git push origin HEAD:main

# Ensure we have a pack
git gc --aggressive --prune=now
pack=$(ls .git/objects/pack/pack-*.pack | head -n1)

# Intentionally corrupt the pack (flip one byte)
printf '\0' | dd of="$pack" bs=1 seek=128 count=1 conv=notrunc status=none || true

# Observe failure
set +e
git fsck --full; status=$?
set -e
[ $status -eq 0 ] && { echo "unexpected: fsck passed"; exit 1; }

echo "Fixing..."
# Isolate bad pack and refetch from remote
mkdir -p .git/objects/pack/quarantine
mv "${pack%.pack}.pack" "${pack%.pack}.idx" .git/objects/pack/quarantine/

git fetch --all --prune --force --tags

git repack -Ad -l

git fsck --full --strict

Step-by-step diagnosis and repair

  1. Confirm corruption
  • Run: git fsck --full --strict
  • Note any bad object IDs or pack names.
  1. Check for alternates or partial clones
  • If .git/objects/info/alternates exists and points to a missing path, remove the invalid line and refetch.
  • For shallow clones: git fetch --unshallow or reclone if practical.
  • For partial clones: run an unfiltered fetch, then repack: git fetch --filter=blob:none --refetch --repack; or simply git fetch --all and git repack -Ad -l.
  1. Isolate and replace corrupt packs
  • Verify packs individually: git verify-pack -v .git/objects/pack/pack-XXXX.pack
  • Move any failing .pack and matching .idx to a quarantine folder.
  • Fetch to restore missing objects: git fetch --all --prune --force --tags
  1. Rebuild repository storage
  • Repack and prune packed objects: git repack -Ad -l
  • Clean up: git gc --prune=now
  • Verify again: git fsck --full --strict
  1. Salvage unpushed work if repairs fail
  • Copy the working tree (excluding .git) to a safe location; you can re-add these files to a fresh clone.
  • If commits exist locally but refs are broken, try: git show <sha> or git cat-file -p <sha> for reachable objects; otherwise, patch from backup copy.

Server/bare repository guidance

  • Run on the server:
    • git fsck --full --strict
    • git verify-pack -v .git/objects/pack/pack-*.pack | less
    • Move failing packs aside; git fetch from an upstream mirror if available.
    • Repack for efficient serving: git repack -Ad --write-bitmap-index
  • If the only copy is corrupted, restore from backup or a healthy mirror. Consider setting up a regular mirror: git clone --mirror and periodic fetch.

Common scenarios and fixes

SymptomLikely causeFix
Error after power lossPartial writeQuarantine bad pack, fetch, repack
Only shallow clone breaksMissing historygit fetch --unshallow, repack
CI runners fail intermittentlyCache corruptionClear VCS cache before job; fetch clean; repack
Submodule checkout failsSubmodule pack corruptRepair inside submodule path, then git submodule sync --recursive
Alternates file points to removed pathBroken alternatesRemove bad alternates entry; fetch; repack

Pitfalls to avoid

  • Do not delete .git/objects entirely; you can lose unpushed history.
  • Do not run git gc --prune aggressively before refetching; you may drop objects you still need.
  • Sync tools and antivirus can corrupt or lock pack files; exclude the .git directory from scanning and from cloud sync folders.
  • Using git filter-repo or history rewrites during corruption can complicate recovery; repair first.

Performance notes

  • Prefer git repack -Ad -l over git gc --aggressive on large repos; it’s faster and usually sufficient.
  • On servers, write bitmaps for faster fetch/clone: git repack -Ad --write-bitmap-index.
  • Use multi-pack index for many packs: git multi-pack-index write; git repack -Ad; git multi-pack-index expire.
  • Enable built-in maintenance: git maintenance start to schedule background gc and incremental repacks.
  • Keep repos off networked filesystems with poor locking; use local SSD where possible.

Prevention

  • Ensure stable storage and power; use UPS on critical servers.
  • Exclude .git from antivirus and file-sync tools.
  • Regularly run git fsck in CI for critical repos and alert on failures.
  • Maintain mirrors and backups; test recovery periodically.

Tiny FAQ

  • Can I just reclone? Yes, if you have pushed all work and the remote is healthy. It’s the fastest fix.
  • Which packs are safe to delete? Only the packs you verified as corrupt, and only after a successful refetch.
  • Will git gc fix this by itself? Not if objects are unreadable. You must replace corrupted packs first, then gc/repack.
  • Does this affect Git LFS? LFS has separate storage. Run git lfs fsck and git lfs fetch --all if LFS is used.
  • What if the remote is also corrupted? Restore from a backup or a healthy mirror, or re-seed from developer clones that still have the history.

Series: Git

DevOps