This error occurs when a Git branch reference file becomes corrupted, typically due to a system crash, power failure, or disk error. The fix involves deleting the corrupted ref file and recovering from the reflog or remote.
Git stores branch references as small text files in the `.git/refs/heads/` directory. Each file contains the 40-character SHA-1 hash of the commit that branch points to. When Git reports "bad ref for .git/refs/heads/main" (or another branch name), it means the reference file exists but contains invalid data. This corruption typically happens when your system loses power or crashes while Git is writing to a ref file. The file may end up containing null bytes, partial data, or be completely empty. Git cannot parse this as a valid commit reference, so it reports the ref as "bad." The good news is that Git's design makes this recoverable in most cases. The actual commit data is stored separately in Git's object database, and the reflog (stored in `.git/logs/`) keeps a history of what each ref pointed to. You can usually restore the correct SHA-1 from these backups.
First, run git fsck to identify all corrupted references:
git fsck --fullThis will list all problematic refs. You can also check the specific file mentioned in the error:
cat .git/refs/heads/mainIf the file is corrupted, you'll see null characters, garbage data, or an empty output instead of a 40-character SHA-1 hash.
Git's reflog tracks recent changes to each ref. Check if the correct SHA is preserved:
# View the reflog for the corrupted branch
tail -n 5 .git/logs/refs/heads/main
# Or use git reflog (may fail if HEAD is also corrupted)
git reflog show mainThe reflog entries look like this:
abc1234 def5678 User <email> 1234567890 +0000 commit: messageThe second SHA (def5678... in full 40-character form) is the most recent commit for that ref.
Once you've identified the correct SHA (or confirmed you can recover from remote), delete the corrupted file:
# Remove the corrupted ref
rm .git/refs/heads/main
# If the logs file is also corrupted, remove it too
rm .git/logs/refs/heads/mainImportant: Only delete the specific corrupted files, not the entire refs directory.
If you found the correct SHA in the reflog, restore the branch:
# Replace <sha> with the 40-character SHA from your reflog
git update-ref refs/heads/main <sha>
# Example:
git update-ref refs/heads/main a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0Verify the restoration:
git log main --oneline -5If you can't find the SHA in the reflog, fetch from the remote repository:
# Fetch all refs from origin
git fetch origin
# Recreate the local branch from the remote
git branch -f main origin/main
# Or checkout the branch
git checkout -B main origin/mainThis will reset your local branch to match the remote, so any unpushed commits will be lost.
After fixing the refs, clean up the repository:
git gc --prune=nowThen verify everything is working:
git fsck --full
git statusIf git fsck reports no errors, your repository is healthy again.
If the corrupted refs were remote tracking branches, prune them:
git remote prune originThis removes any local references to remote branches that no longer exist.
If multiple refs are corrupted and recovery is difficult, clone a fresh copy:
# Clone the repository fresh
git clone <repository-url> project-fresh
# Copy any uncommitted changes from the old repo
cp -r old-project/src/* project-fresh/src/
# Verify and commit your changes
cd project-fresh
git status
git add .
git commit -m "Recover uncommitted changes"This approach preserves all committed history from the remote while recovering your local changes.
### Understanding Git Refs
Git refs are simple text files that map human-readable names to commit SHAs:
- .git/refs/heads/ - Local branches
- .git/refs/remotes/ - Remote tracking branches
- .git/refs/tags/ - Tags
- .git/HEAD - Currently checked out branch/commit
### Packed Refs
For performance, Git may "pack" refs into a single file at .git/packed-refs. If your branch is packed, you may need to edit this file directly:
# Check if branch is in packed-refs
grep "refs/heads/main" .git/packed-refs
# Edit if necessary (use the correct SHA)
# Format: <sha> refs/heads/main### Preventing Future Corruption
1. Use a UPS for systems with important repositories
2. Sync before shutdown: Run git fsck before shutting down
3. Avoid force-killing Git: Let Git operations complete
4. Keep remotes up to date: Push frequently so you have a backup
5. Consider filesystem journaling: ext4, XFS, or NTFS with journaling enabled
### Using git-repair Tool
On Debian/Ubuntu systems, you can install a dedicated repair tool:
sudo apt install git-repair
git-repairThis tool automatically attempts to fix common repository corruption issues.
### WSL and Windows Considerations
If using Git in WSL accessing Windows filesystem (e.g., /mnt/c/), corruption is more likely due to cross-filesystem operations. Keep repositories within the WSL filesystem (~/) for better reliability.
fatal: bad object in rev-list input
Git rev-list encounters bad or invalid object
fatal: Out of memory, malloc failed during pack operation
Out of memory during Git pack operation
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git