When Git can't find an object it expects, operations fail with "missing" or "bad object" errors. This typically happens after disk issues, interrupted operations, or corruption.
The Error
Running git commands:
git logYou see:
fatal: bad object HEADOr:
git statuserror: Could not read abc1234567890abcdef1234567890abcdef1234
fatal: unable to read tree abc1234...Or:
git fsckmissing blob 1234567890abcdef1234567890abcdef12345678
missing commit abcdef1234567890abcdef1234567890abcdef12
missing tree def1234567890abcdef1234567890abcdef123456Types of Missing Objects
Git has three object types:
- Blob - File contents
- Tree - Directory structure
- Commit - Commit metadata and references
Any can go missing, causing different symptoms:
| Missing Type | Symptoms |
|---|---|
| Blob | Can't read file at commit, checkout fails |
| Tree | Can't list directory, ls-tree fails |
| Commit | Can't see history, log stops |
Diagnosis Steps
Run full filesystem check:
``bash
git fsck --full --unreachable
Output shows what's missing:
``
missing blob 4a2b3c4d5e6f7890...
missing commit 1a2b3c4d5e6f7890...
dangling tree 5a6b7c8d9e0f1234...
Check what object is missing:
``bash
git cat-file -t abc1234567890
Returns:
``
error: Could not read abc1234567890...
Or if object exists, returns type:
``
commit
Check pack files:
``bash
git verify-pack -v .git/objects/pack/*.idx
Shows corrupt or missing entries.
Check what commits reference the object:
``bash
git log --all --full-history -- <path>
Solution 1: Fetch from Remote
The easiest fix if remote has the objects:
git fetch origin --allIf missing objects are on the remote:
``bash
git fetch --all --tags
For all remote branches:
``bash
git fetch origin '+refs/*:refs/*'
Solution 2: Repair from Another Clone
If you have another clone of the same repo:
```bash # From the good clone cd /path/to/good-clone git bundle create /tmp/repo.bundle --all
# In the broken clone cd /path/to/broken-clone git bundle unbundle /tmp/repo.bundle ```
Or copy objects directly:
``bash
# Copy missing objects from good repo
rsync -av /path/to/good-clone/.git/objects/ .git/objects/
Solution 3: Unpack and Repack
Sometimes pack files are corrupt:
```bash # Move pack files temporarily mkdir -p /tmp/pack-backup mv .git/objects/pack/* /tmp/pack-backup/
# Unpack objects for pack in /tmp/pack-backup/*.pack; do git unpack-objects < "$pack" done
# Repack git repack -a -d ```
Solution 4: Remove Empty Object Files
Empty files can cause errors:
find .git/objects -type f -emptyRemove them:
``bash
find .git/objects -type f -empty -delete
Solution 5: Restore Specific Objects
If you know what content is missing:
For a blob (file content):
``bash
# If you know the file contents
echo "correct file content" | git hash-object -w --stdin
This creates the object in the database.
For a commit:
If you have the commit hash from reflog:
``bash
git reflog
Find the commit and create a branch:
``bash
git branch recovered abc1234567890
Solution 6: Fix Missing Trees
If a tree object is missing:
# Find commits that reference the tree
git log --all --pretty=format:'%H %T' | grep <tree-hash>Checkout parent commit and recreate:
``bash
git checkout <parent-commit>
git add .
git write-tree
Solution 7: Recover from Reflog
Reflog may have references to missing commits:
git reflog show --allRecover:
``bash
git branch recovery-branch HEAD@{5}
Solution 8: Clone Fresh
When corruption is extensive:
```bash # Backup uncommitted work cp -r src /tmp/src-backup
# Note current branch git branch --show-current
# Clone fresh cd .. git clone <remote-url> new-repo cd new-repo
# Restore uncommitted work cp -r /tmp/src-backup/* src/ ```
Solution 9: Partial Recovery
Recover what you can:
```bash # Create list of missing objects git fsck --full 2>&1 | grep "missing" > missing.txt
# Try to fetch each from remote while read -r type hash; do git fetch origin "$hash" 2>/dev/null || echo "Could not fetch $hash" done < missing.txt ```
Verification
Check fsck is clean:
``bash
git fsck --full
Should show no errors or only "dangling" objects (which are normal).
Test operations:
``bash
git log --oneline -10
git status
git diff HEAD~1
Verify all branches:
``bash
git branch -a
for branch in $(git branch -a | sed 's/^[* ]*//'); do
git log "$branch" --oneline -1 || echo "Branch $branch is broken"
done
Prevention
Enable gc auto:
``bash
git config --global gc.auto 256
git config --global gc.autoPruneExpire never
Regular maintenance:
``bash
git gc --prune=now
git fsck --full
Use a backup remote:
``bash
git remote add backup /path/to/backup.git
git push backup --all
Common Scenarios
Scenario: Missing blob after crash
error: Could not read 4a2b3c4d...
fatal: unable to read working treeFix: ```bash # Check what file is affected git ls-tree -r HEAD | grep 4a2b3c4d
# If you have the content elsewhere, recreate echo "content" | git hash-object -w --stdin
# Or fetch from remote git fetch origin git checkout HEAD -- <affected-file> ```
Scenario: Missing commit in history
fatal: bad object abc1234Fix: ```bash # Try remote git fetch origin
# Check reflog git reflog
# Find and recover git branch recovered-commit HEAD@{3} ```
Scenario: Pack file corruption
error: object pack <hash> is corruptFix:
``bash
rm .git/objects/pack/*.idx
rm .git/objects/pack/*.pack
git fetch --all
git repack -a -d