Skip to content
ohsudo, Home
CI/CD

Git "error: src refspec main does not match any": commit first, or use the right branch name

Fix Git "error: src refspec main does not match any" on push: you have no commits yet, or your branch is called master. Check with git branch, then commit or rename it.

Beginner4 min readApplies to Git 2.x · GitHub · GitLab · Bitbucket

by OhSudo ··

Checked on real software: Git · November 2026How we check

Part of a learning path:Git for everyday work

$ git push -u origin main
error: src refspec main does not match any
error: failed to push some refs to 'github.com:acme/app.git'

“src” is the source, your side. git push origin main means “send my local branch main”, and you don’t have a local branch by that name. The server has nothing to do with it. Nothing has even been sent yet.

There are two common reasons: you have no commits yet, or your branch is called something else, usually master.

  1. git push origin mainsend my local main
  2. Your repositoryno commit yet, or the branch is master(breaks here)
  3. The servernever contacted
src is your side: git push origin main sends your local branch main. Nothing was sent; there's no local branch by that name, usually because there are no commits yet or it's called master.

TL;DR

Terminal window
git status
git branch
git log --oneline -n 1

No commits? Then:

Terminal window
git add .
git commit -m "First commit"
git push -u origin main

On master? Rename it, then push:

Terminal window
git branch -M main
git push -u origin main

1. No commits yet

A branch doesn’t really exist until it has a commit. After git init, you’re on a name with nothing behind it. You can try this in the terminal, in a project that’s just been through git init:

Terminal window
git status
On branch main
No commits yet

So commit something first:

Terminal window
git add .
git commit -m "First commit"
git push -u origin main

Three things can get in the way:

Nothing got staged. A .gitignore that catches everything, or an empty folder (Git doesn’t track empty folders). git status shows what’s there, and git check-ignore -v file explains why a file’s ignored. See why .gitignore doesn’t work, and the .gitignore Generator can give you a sensible file.

The commit failed. Scrolled past? A commit needs your name and email, and without them it stops with this:

Author identity unknown
*** Please tell me who you are.
Terminal window
git config --global user.name "Your Name"
git config --global user.email "you@example.com"

A failing pre-commit hook also stops a commit, with its own message.

You’re in the wrong folder. A different repository, or none. git rev-parse --show-toplevel shows where you are.

2. The branch has another name

Terminal window
git add .
git commit -m "First commit"
git branch
* master

Many tutorials say main, and GitHub creates new repositories with main. But git init still uses master unless you’ve changed it, so the two often don’t match. You can push under the name you have:

Terminal window
git push -u origin master

Or rename it, which is what most people want:

Terminal window
git add .
git commit -m "First commit"
git branch -M main
git push -u origin main

Make new repositories start with main:

Terminal window
git config --global init.defaultBranch main

Not sure what’s on the server?

Terminal window
git ls-remote --heads origin
git remote show origin | grep 'HEAD branch'

3. A typo, or case

Refspecs are exact, so these all fail if your branch is main:

Terminal window
git push origin Main
git push origin mian
git push origin feature/login # the branch is feature/Login, or features/login

Case is a special trap on Windows and macOS, where the file system can hide it. Use the name exactly as git branch shows it, or skip typing it, as HEAD means your current branch:

Terminal window
git push -u origin HEAD

Pushing a tag? It has to exist locally too:

Terminal window
git tag
git tag v1.0.0
git push origin v1.0.0

4. A detached HEAD

Here git status starts with:

HEAD detached at 4f2a91c

You’ve checked out a commit rather than a branch, so main may exist, without your new work on it. Save the work on a branch:

Terminal window
git switch -c my-work
git push -u origin my-work

That’s what happens by default in many CI checkouts. In a pipeline, push with an explicit source and target:

Terminal window
git push origin HEAD:refs/heads/main

5. The first push is empty, and the remote isn’t

You’ve solved this one, and the next message appears:

! [rejected] main -> main (fetch first)

Good news: your side’s fine now. The remote has commits you don’t, often because GitHub created a README. See git push rejected. And if Git then refuses to merge the two, see refusing to merge unrelated histories. Creating the repository empty avoids both.

A git push origin HEAD:main from a fresh repository still fails with the same message here, as HEAD doesn’t point at a commit yet. The answer is still to commit first.

Warning

Forums sometimes suggest git push --force for push errors. It does nothing for this one, as your side has nothing to send. And on the next error, it can overwrite the remote’s history, so take a look at what’s there first.

Shell, we have a problem!

Similar, but different: src refspec main matches more than one means a branch and a tag share that name: use refs/heads/main. fatal: The current branch has no upstream branch means you need -u origin main once. Permission denied (publickey) is about your SSH key: see that article. remote: Repository not found usually means a wrong URL, or no access. All the everyday commands are in the Git Cheat Sheet.

$ ./practice.sh

Practice this in the terminal

Open the Terminal Playground with this article’s scenario loaded. It is safe and runs in your browser.

Open the terminal →

Found this useful? Share it.

Found a mistake? Let us know at contact@ohsudo.com.

Tools

Try it yourself

Articles

Related articles