KhueApps
Home/DevOps/Fix Git error: fatal: couldn't find remote ref

Fix Git error: fatal: couldn't find remote ref

Last updated: October 07, 2025

What this error means

Git could not find the branch, tag, or ref path you asked it to fetch, pull, or checkout from the remote. Typical causes:

  • The branch/tag does not exist on the remote.
  • Wrong name (typo or case mismatch) or wrong namespace (heads vs tags).
  • Remote URL points to a different repository.
  • Shallow/partial fetch omitted the ref.
  • Misconfigured refspec in .git/config or CI.

Common contexts: git fetch origin feature-x, git pull origin develop, git checkout tags/v1.2.0, or CI fetching PR refs.

Quickstart (most cases)

  1. Verify the ref exists on the remote:
# Branches
git ls-remote --heads origin feature-x
# Tags
git ls-remote --tags origin v1.2.0
  • If no output, the ref is not on the remote.
  1. Refresh your local view of the remote:
git fetch origin --prune --tags
  1. Use the correct name and namespace:
# Branch
git fetch origin feature-x:feature-x && git switch feature-x
# Tag
git fetch origin refs/tags/v1.2.0 && git checkout tags/v1.2.0
  1. If the branch doesn’t exist remotely but you want it there:
git switch -c feature-x
# commit something
git push -u origin feature-x

Minimal working example (reproduce and fix)

# 1) Create a bare remote with only 'main'
rm -rf /tmp/remote.git /tmp/work
git init --bare /tmp/remote.git

git clone /tmp/remote.git /tmp/work
cd /tmp/work
git commit --allow-empty -m "init"
# publish 'main'
git push -u origin HEAD:refs/heads/main

# 2) Try to fetch non-existent 'develop' (triggers error)
 git fetch origin develop
# fatal: couldn't find remote ref develop

# 3) Two fixes:
# A) Use an existing remote branch
git fetch origin main:main && git switch main

# B) Create 'develop' on remote and then fetch it
git switch -c develop
git commit --allow-empty -m "start develop"
git push -u origin develop
# Now fetching works
git fetch origin develop:develop && git switch develop

Diagnose by scenario

SymptomLikely causeWhat to do
fatal: couldn't find remote ref feature-xBranch doesn’t exist on remotegit ls-remote --heads origin, push the branch or use an existing one
fatal: couldn't find remote ref v1.2.0Tag missing or not fetchedgit ls-remote --tags origin, git fetch --tags, or create the tag
Works locally, CI failsShallow or selective fetch in CIAdd explicit fetch refspec for needed branches/tags, adjust depth
Only fails on Linux remoteCase mismatch (Feature vs feature)Use exact case; Git refs are case-sensitive on most servers
After default branch renameStale origin/HEAD or wrong branch namegit remote set-head origin -a, verify main vs master
New remote URL, same local checkoutWrong origin URLgit remote -v, git remote set-url origin <correct-url>

Step-by-step troubleshooting

  1. Confirm the remote and URL:
git remote -v
  1. See what the remote actually has:
# All refs (heads, tags, etc.)
git ls-remote origin | head -n 20
# Specific branch or tag
git ls-remote --heads origin <branch>
git ls-remote --tags origin <tag>
  1. Refresh local refs and prune stale ones:
git fetch origin --prune --tags
  1. Specify full refnames when in doubt:
# Branch
git fetch origin refs/heads/feature-x:refs/remotes/origin/feature-x
# Tag
git fetch origin refs/tags/v1.2.0:refs/tags/v1.2.0
  1. Check for typos and case sensitivity:
  • Feature-Xfeature-x on most servers.
  • Ensure you are not mixing refs/heads/ (branches) with refs/tags/ (tags).
  1. Review refspecs in .git/config (advanced):
[remote "origin"]
    url = git@host:org/repo.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    # Optional: fetch PR refs or additional namespaces if your platform supports them
    # fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
[fetch]
    prune = true
  1. Adjust shallow/partial clones (CI):
# Fetch only what you need, but include the target ref
# Example: fetch a single branch with depth
git fetch --depth 50 origin refs/heads/feature-x:refs/remotes/origin/feature-x

Common fixes by task

  • Pulling a branch that is new locally:
    • git push -u origin <branch> then git switch <branch>.
  • Checking out a tag that isn’t fetched:
    • git fetch --tags or git fetch origin refs/tags/<tag> then git checkout tags/<tag>.
  • Sync after default branch rename:
    • git fetch origin --prune and git remote set-head origin -a; update branch names in scripts.
  • CI fetching a PR:
    • Use provider-specific ref (e.g., refs/pull/123/head) or fetch the merge ref if available.

Pitfalls

  • Assuming tags are always fetched: by default only tags reachable from fetched commits arrive; use git fetch --tags or explicit tag ref.
  • Overwriting refspecs: replacing instead of adding lines in .git/config can hide refs.
  • Case mismatch across OS: Windows/macOS may not reveal a case error that fails on Linux CI.
  • Detached HEAD confusion: HEAD is not a branch; use explicit branch names.

Performance notes

  • Prefer selective fetch over fetching all refs in CI:
    • git fetch origin refs/heads/<branch>:refs/remotes/origin/<branch>
  • Use shallow depth judiciously; if you need tags or multiple branches, either increase depth or fetch specific refs explicitly.
  • Enable pruning to keep remote-tracking branches clean:
    • git config fetch.prune true
  • Avoid unnecessary --tags on every fetch if you don’t use tags; fetch them only when needed.

FAQ

  • Why does pushing work but pulling fails with this error?

    • git push origin <branch> creates the remote branch; git pull origin <branch> fails only if that branch didn’t exist previously or you mistyped it.
  • How do I fetch a single tag without all tags?

    • git fetch origin refs/tags/v1.2.3:refs/tags/v1.2.3 then git checkout tags/v1.2.3.
  • How do I verify the exact ref name the server exposes?

    • git ls-remote origin and look for refs/heads/<branch> or refs/tags/<tag>.
  • Can a bad remote URL cause this?

    • Yes. If origin points to the wrong repo, the ref likely won’t exist. Use git remote set-url origin <correct-url>.

Series: Git

DevOps