Skip to content
Latchkey

Git "fatal: couldn't find remote ref" in CI

Git asked the remote for a specific ref and the remote does not have it. The branch or tag name is wrong, was deleted, or the ref simply was never created on the remote you are pointing at.

What this error means

A fetch or checkout of a named ref fails with fatal: couldn't find remote ref <ref>. Other refs in the same repo fetch fine - only this branch/tag/SHA is missing on the remote.

git fetch output
fatal: couldn't find remote ref refs/heads/relase-2.0
# or
fatal: couldn't find remote ref v1.2.3

Diagnose it: depth, refs, or credentials?

CI checkouts are shallow and detached by default, which breaks anything that needs history or a branch name. Before treating it as a credential problem, confirm what the runner actually fetched.

.github/workflows/ci.yml
- run: |
    git rev-parse --is-shallow-repository
    git rev-parse --abbrev-ref HEAD      # prints HEAD when detached
    git log --oneline -3
    git remote -v
    git for-each-ref --format="%(refname)" | head

Common causes

The branch or tag name is wrong or deleted

A typo (relase vs release), a branch that was merged and deleted, or a tag that was never pushed all mean the remote has no such ref to return.

The default branch was renamed

A job hard-coded to master fails against a repo whose default branch is now main (or vice versa). The old name no longer exists on the remote.

Tags were never fetched

A shallow or --no-tags clone may not know about a tag, so a checkout of that tag asks the remote for a ref the local clone never mirrored.

How to fix it

List what the remote actually has

Confirm the exact ref name before checking it out.

Terminal
git ls-remote --heads --tags https://github.com/org/repo.git
# grep for the branch/tag you expect

Reference the correct ref

  1. Fix typos and use the repo’s real default branch (main vs master).
  2. For tag checkouts, ensure tags are fetched (fetch-tags: true or git fetch --tags).
  3. In a workflow, use a context value (e.g. the default branch) instead of hard-coding a branch name.

The checkout options that fix most of this

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0        # full history: diffs, tags, git describe
    submodules: recursive # submodules are NOT fetched by default
    persist-credentials: false  # if a later step pushes with its own token

How to prevent it

  • Derive the default branch dynamically instead of hard-coding main/master.
  • Fetch tags when a job checks out tagged releases.
  • Validate ref names with git ls-remote in scripts that take a branch/tag input.

Frequently asked questions

What causes Git "fatal: couldn't find remote ref" in CI?
There are 3 common causes: the branch or tag name is wrong or deleted, the default branch was renamed, and tags were never fetched. A typo (relase vs release), a branch that was merged and deleted, or a tag that was never pushed all mean the remote has no such ref to return.
How do I fix Git "fatal: couldn't find remote ref" in CI?
There are 2 fixes depending on which cause you have: list what the remote actually has and reference the correct ref. Work through them in order, since the first is the most common.
What does Git "fatal: couldn't find remote ref" in CI actually mean?
A fetch or checkout of a named ref fails with fatal: couldn't find remote ref <ref>.
How do I stop Git "fatal: couldn't find remote ref" in CI happening again?
Derive the default branch dynamically instead of hard-coding main/master. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card