How to fix fatal: couldn't find remote ref in Git

GitBEGINNERMEDIUMUpdated Oct 14, 2026ยท 647 views

Fix Git's "fatal: couldn't find remote ref" error caused by deleted, renamed, or stale branch refs. Run git fetch --prune and check the exact branch name.

Quick fix

Fixes fatal: couldn't find remote ref

# Fetch the latest remote info
git fetch origin

# List all remote branches
git branch -r

# Or list all branches (local and remote)
git branch -a
  1. Verify the branch exists on the remote
  2. Check for branch name typos or casing issues
  3. Update stale remote tracking branches
  4. Fix CI/CD pipeline configuration
git โ€” error
# Fetch the latest remote info
git fetch origin
# List all remote branches
git branch -r
# Or list all branches (local and remote)
git branch -a
fatal: couldn't find remote ref

What this error means

The "fatal: Couldn't find remote ref refs/heads/branch-name" error indicates that Git attempted to fetch or checkout a branch from the remote repository, but that branch does not exist there. The refs/heads/ prefix refers to branches (as opposed to refs/tags/ for tags), and Git is explicitly stating it cannot find the specified branch reference. This error commonly appears in CI/CD environments where pipeline configurations reference branches that have been deleted, merged, or renamed since the configuration was written. It can also occur when a developer tries to checkout a branch that was only created locally by a teammate and never pushed to the remote. The error is particularly common after branch cleanup operations, pull request merges with automatic branch deletion enabled, or when switching between repositories that have different branch structures.

Typical symptoms

  • Git fetch or git pull fails with 'Couldn't find remote ref' error
  • CI/CD pipeline fails during checkout step with fatal error
  • GitHub Actions, GitLab CI, or Jenkins job aborts at git checkout
  • Attempting 'git checkout origin/branch-name' fails
  • Error appears after a branch was recently merged or deleted
  • Clone with specific branch flag fails: 'git clone -b branch-name'
  • Submodule update fails when submodule references non-existent branch
  • Deployment scripts fail when targeting specific branch

Common causes

  1. The branch was deleted from the remote repository after merge
  2. Branch name is misspelled or uses wrong casing
  3. CI/CD pipeline configuration references an outdated branch name
  4. Branch exists locally but was never pushed to the remote
  5. Repository was forked and the branch only exists in the upstream repository
  6. Default branch was renamed (e.g., master to main) but references not updated
  7. Protected branch was force-deleted by admin
  8. Submodule configuration points to a branch that no longer exists

How to fix "fatal: couldn't find remote ref"

1Verify the branch exists on the remote

First, check which branches actually exist on the remote repository:

bash
# Fetch the latest remote info
git fetch origin

# List all remote branches
git branch -r

# Or list all branches (local and remote)
git branch -a

If your target branch is not in the list, it either never existed or has been deleted. You can also check directly on GitHub/GitLab web interface to confirm.

To see when branches were deleted (if you have access to reflog):

bash
git reflog show --all | grep "branch-name"
2Check for branch name typos or casing issues

Branch names are case-sensitive on most Git hosting platforms. Verify the exact spelling:

bash
# List remote branches and search for similar names
git branch -r | grep -i "branch"

# Check if using different casing
git branch -r | grep -i "feature"

Common mistakes include:
- Feature/login vs feature/login
- develop vs development
- master vs main

If you find the correct name, update your command or CI configuration accordingly.

3Update stale remote tracking branches

Your local repository might have stale references to branches that no longer exist. Prune them:

bash
# Prune deleted remote branches
git fetch --prune

# Or prune specifically from origin
git remote prune origin

# Verify the cleanup
git branch -r

After pruning, if you still need to reference a branch that was deleted, you'll need to recreate it or update your workflow to use an existing branch.

4Fix CI/CD pipeline configuration

If this error occurs in CI/CD, update the pipeline configuration to reference an existing branch.

GitHub Actions:

yaml
# .github/workflows/ci.yml
on:
  push:
    branches:
      - main  # Update from old branch name
      - develop
  pull_request:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: main  # Ensure this branch exists

GitLab CI:

yaml
# .gitlab-ci.yml
default:
  # Remove hardcoded branch references if not needed

deploy:
  script:
    - echo "Deploying..."
  only:
    - main  # Update to existing branch

Jenkins:

groovy
// Jenkinsfile
pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main',  // Update branch name
                    url: 'https://github.com/user/repo.git'
            }
        }
    }
}
5Handle default branch rename (master to main)

If your repository's default branch was renamed, update all references:

bash
# Update your local default branch
git branch -m master main
git fetch origin
git branch -u origin/main main
git remote set-head origin -a

# Verify the change
git remote show origin

Update any CI/CD configurations, deployment scripts, or documentation that references the old branch name.

To find files referencing old branch names:

bash
# Search for 'master' references in config files
grep -r "master" .github/ .gitlab-ci.yml Jenkinsfile 2>/dev/null
6Recreate the branch if needed

If you need to restore a deleted branch, you may be able to recover it:

bash
# If you have the branch locally
git push origin branch-name

# If you know the last commit hash
git checkout -b branch-name <commit-hash>
git push origin branch-name

On GitHub, recently deleted branches from merged PRs can often be restored via the web interface:
1. Go to the closed Pull Request
2. Look for "Restore branch" button

If the branch was never pushed, you'll need to get it from whoever created it locally.

7Fix submodule branch references

If the error occurs during submodule operations, update the submodule configuration:

bash
# Check submodule status
git submodule status

# View submodule configuration
cat .gitmodules

Update the branch in .gitmodules:

ini
[submodule "libs/mylib"]
    path = libs/mylib
    url = https://github.com/user/mylib.git
    branch = main  # Update to existing branch

Then sync the changes:

bash
git submodule sync
git submodule update --init --recursive
8Use default branch dynamically in scripts

To avoid hardcoding branch names in scripts, detect the default branch programmatically:

bash
# Get the default branch name from remote
DEFAULT_BRANCH=$(git remote show origin | grep "HEAD branch" | cut -d ":" -f 2 | xargs)

# Use it in your commands
git checkout "$DEFAULT_BRANCH"
git pull origin "$DEFAULT_BRANCH"

In GitHub Actions:

yaml
- name: Get default branch
  run: |
    DEFAULT_BRANCH=$(git remote show origin | grep "HEAD branch" | cut -d ":" -f 2 | xargs)
    echo "DEFAULT_BRANCH=$DEFAULT_BRANCH" >> $GITHUB_ENV

- name: Checkout default
  run: git checkout ${{ env.DEFAULT_BRANCH }}

This approach is more resilient to branch renames.

Advanced notes

### Understanding Git Refs

Git references (refs) are pointers to commits. The refs/heads/ namespace contains branches:
- refs/heads/main - the main branch
- refs/tags/v1.0.0 - a tag
- refs/remotes/origin/main - remote tracking branch

When you see "Couldn't find remote ref refs/heads/branch-name", Git looked in the remote's refs/heads/ namespace and found nothing matching "branch-name".

### Shallow Clone Considerations

CI/CD systems often use shallow clones for speed, which can cause ref-related issues:

bash
# Shallow clone only fetches limited history
git clone --depth 1 https://github.com/user/repo.git

# If you need to checkout a different branch
git fetch --unshallow
git fetch origin other-branch
git checkout other-branch

Or specify the branch during shallow clone:

bash
git clone --depth 1 --branch main https://github.com/user/repo.git

### Checking Remote Without Cloning

To verify a branch exists before attempting operations:

bash
# List remote refs without cloning
git ls-remote --heads origin

# Check for specific branch
git ls-remote --heads origin branch-name

# Returns nothing if branch doesn't exist
# Returns ref and hash if it does

This is useful in scripts to validate before attempting checkout.

### Common CI/CD Gotchas

GitHub Actions with pull_request events:
The GITHUB_REF for PRs points to refs/pull/123/merge, not the source branch. If your workflow assumes a branch name, it may fail.

Forked repository PRs:
When a PR comes from a fork, the source branch exists in the fork, not the main repository. Checkout requires special handling:

yaml
- uses: actions/checkout@v4
  with:
    ref: ${{ github.event.pull_request.head.sha }}

### Debugging Ref Issues

Enable Git tracing to see exactly what Git is doing:

bash
GIT_TRACE=1 GIT_CURL_VERBOSE=1 git fetch origin branch-name

This shows the HTTP requests and responses, helping identify if the branch exists but is inaccessible vs. truly missing.

### Protected and Hidden Branches

Some Git hosting platforms allow hiding branches from normal listing:
- GitLab protected branches may have visibility restrictions
- GitHub branch protection doesn't hide branches but may prevent operations
- Some enterprise setups use branch namespacing that affects visibility

Check repository settings if a branch should exist but doesn't appear in listings.

Frequently asked questions

What does "fatal: couldn't find remote ref" mean?
The "fatal: Couldn't find remote ref refs/heads/branch-name" error indicates that Git attempted to fetch or checkout a branch from the remote repository, but that branch does not exist there. The refs/heads/ prefix refers to branches (as opposed to refs/tags/ for tags), and Git is explicitly stating it cannot find the specified branch reference. This error commonly appears in CI/CD environments where pipeline configurations reference branches that have been deleted, merged, or renamed since the configuration was written.
How do I fix "fatal: couldn't find remote ref"?
Fix Git's "fatal: couldn't find remote ref" error caused by deleted, renamed, or stale branch refs. Run git fetch --prune and check the exact branch name.
What causes "fatal: couldn't find remote ref"?
The branch was deleted from the remote repository after merge Branch name is misspelled or uses wrong casing CI/CD pipeline configuration references an outdated branch name
Is the "fatal: couldn't find remote ref" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading