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:

bash
git log

You see:

bash
fatal: bad object HEAD

Or:

bash
git status
bash
error: Could not read abc1234567890abcdef1234567890abcdef1234
fatal: unable to read tree abc1234...

Or:

bash
git fsck
bash
missing blob 1234567890abcdef1234567890abcdef12345678
missing commit abcdef1234567890abcdef1234567890abcdef12
missing tree def1234567890abcdef1234567890abcdef123456

Types 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 TypeSymptoms
BlobCan't read file at commit, checkout fails
TreeCan't list directory, ls-tree fails
CommitCan'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:

bash
git fetch origin --all

If 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:

bash
find .git/objects -type f -empty

Remove 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:

bash
# 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:

bash
git reflog show --all

Recover: ``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

bash
error: Could not read 4a2b3c4d...
fatal: unable to read working tree

Fix: ```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

bash
fatal: bad object abc1234

Fix: ```bash # Try remote git fetch origin

# Check reflog git reflog

# Find and recover git branch recovered-commit HEAD@{3} ```

Scenario: Pack file corruption

bash
error: object pack <hash> is corrupt

Fix: ``bash rm .git/objects/pack/*.idx rm .git/objects/pack/*.pack git fetch --all git repack -a -d