The Error
You run a routine git status, git pull, or even just git log and suddenly hit this:
error: object file .git/objects/ab/cdef1234567890abcdef is empty
fatal: loose object abcdef1234567890 (stored in .git/objects/ab/cdef1234567890) is corrupt
Git grinds to a halt. Commit, pull, push โ none of it works. Sometimes you can't even run git status. The usual suspects: a hard shutdown while Git was writing, a disk that ran out of space mid-operation, or a power cut during git gc. Any of these can leave zero-byte or partial object files behind, and Git refuses to continue until they're dealt with.
Step 1 โ Run fsck to see the full damage
Don't touch anything yet. First, map out exactly what's broken:
git fsck --full
This scans every object in .git/objects/ and flags missing, dangling, or corrupt entries. Output typically looks like this:
error: object file .git/objects/ab/cdef1234567890abcdef is empty
error: object file .git/objects/3f/a0b12c... is empty
dangling blob 7d3e9f...
missing tree 8c12a4...
In a bad case you might see 5โ10 corrupt hashes listed. Write them all down โ you'll reference them later.
Step 2 โ Remove the empty object files
Zero-byte files are the most common symptom. Git can't parse an empty object and won't proceed past one. Delete them:
# Dry run first โ see what would be deleted
find .git/objects -size 0
# Delete all zero-byte object files
find .git/objects -size 0 -delete
Run git fsck --full again afterward. If those objects existed on a remote or in your reflog, Git can often recover them in the next steps without any extra work from you.
Step 3 โ Fetch from remote to restore missing objects
A remote makes recovery straightforward. Fetching pulls back the missing objects directly from GitHub, GitLab, or wherever you push to:
git fetch --all
If fetch chokes because HEAD or the current branch ref is itself corrupt, target a specific branch instead:
git fetch origin main
git fetch origin --tags
Run git fsck --full once more. For most people, this single fetch clears the corruption entirely.
Step 4 โ Recover from reflog if the remote fetch isn't enough
Tucked inside .git/logs/ is a chronological journal of every HEAD movement โ Git's reflog. Even when an object is gone, the reflog still knows where HEAD was pointing before things went sideways:
git reflog
Spot the last clean commit (right before the corruption timestamp) and reset to it:
git reset --hard <commit-hash>
If the reflog itself is unreadable, inspect the raw file directly:
cat .git/logs/HEAD
Step 5 โ Rebuild the index if git status is still broken
The index file (.git/index) sometimes takes damage alongside the objects. Delete it and let Git reconstruct it from the HEAD tree:
rm .git/index
git reset HEAD
Your working directory files stay untouched. Git just rebuilds the index from the current commit's tree, which is usually enough to get git status working again.
Step 6 โ Run gc to clean up and repack
With the corruption cleared, consolidate the surviving loose objects into pack files and prune any dangling refs:
git gc --aggressive --prune=now
This also rebuilds internal indexes and can resolve consistency warnings that fsck flagged but didn't classify as hard errors.
Nuclear option โ clone fresh if remote exists
When nothing else works and a clean remote is available, stop fighting the damaged repo and start fresh:
# Back up uncommitted changes first
cp -r my-repo /tmp/my-repo-backup
# Clone fresh
git clone git@github.com:user/my-repo.git my-repo-fresh
# Copy back any untracked files you need
cp /tmp/my-repo-backup/some-file.txt my-repo-fresh/
Verify the fix
Run these four checks to confirm the repo is healthy:
# Should report no errors
git fsck --full
# Should show clean status
git status
# Should print the log without errors
git log --oneline -10
# Test an actual operation
git pull
A clean git fsck with zero error: lines means the object database is intact. You're good.
Prevent it from happening again
- Never force-kill a Git process โ always let
git gc,git clone, orgit pushfinish naturally. - Watch your disk space โ object writes fail silently when the disk runs out mid-operation. Keep at least a few GB free on machines with active repos.
- Use a UPS on machines that matter โ abrupt power loss during a pack operation is the #1 cause of this error. A cheap UPS eliminates the risk entirely.
- Push frequently โ the remote is your real backup. If the objects exist there, recovery is one
git fetchaway. - Run
git fsckperiodically on important repos โ one corrupt object caught early takes seconds to fix. A dozen caught late can mean hours of recovery work.

