This error occurs when Git expects a symbolic reference (like HEAD pointing to a branch) but finds a direct commit SHA or corrupted reference instead. Most commonly happens in detached HEAD state or with corrupted .git files.
A symbolic reference in Git is a special type of reference that points to another reference rather than directly to a commit. The most common symbolic ref is HEAD, which normally contains `ref: refs/heads/branch-name` to point to your current branch. When Git says "ref HEAD is not a symbolic ref," it means HEAD contains a raw commit SHA-1 hash (detached HEAD state) or the reference file is corrupted or malformed. This error typically appears when operations that require an attached HEAD are attempted, such as certain CI/CD workflows, interactive rebases, or automated release processes that use git symbolic-ref to determine the current branch name. In normal Git operations, HEAD is attached to a branch, allowing commits to update that branch automatically. When HEAD points directly to a commit instead, you're in "detached HEAD" state, which is valid for viewing history but problematic for tools expecting a branch context.
First, verify whether you're in a detached HEAD state or if there's actual corruption:
# Check repository status
git status
# Try to read the symbolic ref
git symbolic-ref HEAD
# Examine the HEAD file directly
cat .git/HEADIf .git/HEAD contains a 40-character SHA-1 hash instead of ref: refs/heads/branch-name, you're in detached HEAD state. If the file is missing or malformed, it's corrupted.
If you're in detached HEAD state and want to keep your current position, create a new branch:
# Create a new branch from current position
git checkout -b new-branch-name
# Or switch to an existing branch
git checkout main
# or
git switch mainIf you want to return to your previous branch without keeping detached changes:
# Find your previous branch from reflog
git reflog
# Check out the branch you were on
git checkout branch-nameIf the .git/HEAD file is corrupted or missing, you need to manually restore it. First, identify your intended branch:
# Check available branches
git branch -a
# Check reflog to see what you were working on
tail -n 10 .git/logs/HEADThen recreate the HEAD file pointing to your main branch:
# For main branch
echo 'ref: refs/heads/main' > .git/HEAD
# For master branch
echo 'ref: refs/heads/master' > .git/HEAD
# Verify it worked
git symbolic-ref HEAD
git statusIf the error involves refs/remotes/origin/HEAD, reset it to match the remote's default branch:
# Auto-detect and set origin HEAD
git remote set-head origin --auto
# Or manually set it
git remote set-head origin main
# Verify the fix
git branch -rAlternatively, you can update the symbolic ref directly:
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
# Clean up and prune
git fetch --prune
git gcIf this error occurs in Jenkins, Travis, or other CI systems, configure them to check out to a specific local branch instead of detached HEAD:
Jenkins:
- In job configuration, under "Source Code Management" → "Git"
- Under "Additional Behaviours", add "Check out to specific local branch"
- Specify the branch name (e.g., main, master, or the branch variable)
Travis CI (.travis.yml):
GitLab CI (.gitlab-ci.yml):
Understanding Symbolic vs Direct References:
Git stores two types of references: symbolic references (files containing ref: path/to/ref) and direct references (files containing raw SHA-1 hashes). Symbolic refs are indirection layers that allow HEAD to "follow" a branch. When you commit on an attached HEAD, the symbolic ref means the commit updates both HEAD and the branch it points to.
Dangling Symbolic References:
A "dangling" symbolic ref (one pointing to a non-existent target) is usually harmless. Git won't complain about a dangling HEAD in a new empty repository, and dangling refs/remotes/origin/HEAD references are safe to ignore. However, operations like git gc may issue warnings.
Empty Repositories:
In brand-new repositories with no commits, HEAD exists as a symbolic ref pointing to refs/heads/main (or master), but that branch doesn't exist yet. This is normal and resolves automatically on the first commit.
The -q Flag:
When scripting, use git symbolic-ref -q HEAD to suppress error messages for detached HEAD states. The command will exit with non-zero status silently, allowing you to handle detached HEAD gracefully:
if git symbolic-ref -q HEAD >/dev/null 2>&1; then
echo "HEAD is attached"
else
echo "HEAD is detached"
fiGit 2.48+ Improvements:
Git 2.48 (Q1 2025) enhanced git fsck to detect curiously formatted ref contents, such as missing line endings after object names, that were previously accepted but not Git-standard.
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
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git