Git "fatal: Bad Object" Repository Corruption Recovery
Quick answer
"fatal: bad object" means Git found an object reference it can't actually resolve to valid, intact data — usually from filesystem corruption, an interrupted...
"fatal: bad object" means Git found an object reference it can't actually resolve to valid, intact data — usually from filesystem corruption, an interrupted operation, or disk issues — and the safest, most reliable recovery path in most cases is re-cloning from a remote that still has good data, rather than attempting to repair the corrupted local repository in place.
The Problem
A Git command fails, reporting a specific object as bad or missing:
fatal: bad object HEAD
error: object file .git/objects/a1/b2c3... is empty
fatal: loose object a1b2c3d4e5f6... is corrupt
Why It Happens
Git stores every commit, tree, and file content as individually addressed objects, referenced by their content hash — corruption occurs when one of these underlying object files on disk becomes damaged, truncated, or unreadable, most commonly from:
- An interrupted disk write (a sudden power loss, a forced shutdown, a system crash) occurring precisely while Git was writing object data
- Underlying disk or filesystem corruption, unrelated to Git itself, affecting files within the
.gitdirectory the same as it might affect any other files on the same failing storage - A failed or interrupted
git gc(garbage collection) operation, which repacks and reorganizes objects, leaving things in an inconsistent state if interrupted partway through - Filesystem-level issues specific to certain storage types or configurations (some network-mounted filesystems, certain sync tools like Dropbox/OneDrive syncing a
.gitdirectory, which is generally not recommended precisely because of this kind of corruption risk)
The Fix
First, assess the actual scope of the corruption using Git's built-in integrity check:
git fsck --full
This reports every object Git can identify as corrupted, missing, or otherwise problematic, giving you a clearer picture of whether this is an isolated, single-object issue or more widespread damage.
If the repository has a remote with intact history (the very common case — most corruption is local, and the remote copy on GitHub/GitLab/etc. remains completely unaffected), the simplest and most reliable recovery is straightforward: back up any uncommitted local work you still need, then re-clone fresh from the remote:
# First, preserve any genuinely uncommitted local changes you still need
cp -r my-project my-project-backup
# Then clone fresh
git clone https://github.com/example/my-project.git my-project-fresh
Manually reapply any uncommitted changes from your backup into the fresh clone — this sidesteps the corruption entirely, since you're working with the remote's known-good object data rather than attempting to repair the damaged local copy.
If you have local commits that were never pushed to the remote (and are therefore not recoverable by re-cloning), and the corruption doesn't affect those specific unpushed commits, you may be able to recover them from the damaged repository before abandoning it — check whether the specific unpushed commits are still intact despite corruption elsewhere:
git log --oneline origin/main..HEAD
# if this succeeds and shows your unpushed commits, they may still be salvageable
If salvageable, you can attempt to export them as patches, which don't depend on the repository's overall object integrity the same way a full clone or fetch operation would:
git format-patch origin/main..HEAD -o /tmp/patches/
Apply these exported patches onto your fresh, re-cloned repository, recovering the actual content of your unpushed work even though the original damaged repository itself is being abandoned:
cd my-project-fresh
git am /tmp/patches/*.patch
If you have access to another clone of the same repository (a teammate's machine, a CI system's cache, a different local clone you happen to have), you can sometimes recover specific missing objects by copying them directly from that other, intact copy's object database — though this is more involved and generally only worth attempting when re-cloning genuinely isn't an option (for example, if the corrupted commits were never pushed anywhere and no patch-based recovery is possible either).
Still Not Working?
If corruption recurs repeatedly on the same machine even after successful recovery, investigate the underlying storage itself rather than continuing to treat each occurrence as an isolated incident — run a filesystem check on the underlying disk, and specifically avoid storing your .git directory on a cloud-sync-monitored folder (Dropbox, OneDrive, Google Drive desktop sync) or a network-mounted drive with unreliable connectivity, both of which are well-known, common sources of recurring Git repository corruption due to how they interact with Git's expectations around atomic, uninterrupted file writes.