error: src refspec main does not match any — Git looked for a local branch called main to push and found none. Either the repository has no commit yet, so the branch does not exist until the first one, or your branch has another name, usually master. Commit first, or push the branch you actually have.

Two commands tell you which case you are in: git branch --show-current prints the branch name, and git log --oneline says whether it has any commits. No commits: add, commit, push. Branch called master: push master, or rename it with git branch -M main and push main.

The error

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

Exit code 1, and nothing reached the remote. The second case, a repository with one commit on master, printed the same two lines.

Why it happens

A refspec is the "what goes where" part of a push: git push origin main is short for main:main, send my local main to main on the remote. The left side, the source, must name something that exists locally. In a new repository made with git init -b main, main is only a name waiting for its first commit. The test asked Git about it right after the failed push:

$ git branch --show-current
main
$ git log --oneline
fatal: your current branch 'main' does not have any commits yet
$ git status -sb
## No commits yet on main
?? README.md

A branch is a pointer to a commit. With no commit there is nothing to point at, so there is no main to send, even though Git already shows the name.

The second cause is a name mismatch. The Git for Windows system config on the test machine set init.defaultBranch to master, so a plain git init made a master branch, while the push command, copied from instructions that assume main, asked for main. git branch --show-current answered master.

The fix

For the empty repository, commit first and push the same command again:

$ git add README.md
$ git commit -m "Add README"
[main (root-commit) d3f9025] Add README
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
$ git push -u origin main
branch 'main' set up to track 'origin/main'.
To ../remote.git
 * [new branch]      main -> main

For the master case, either push the branch that exists:

$ git push -u origin master
branch 'master' set up to track 'origin/master'.
To ../remote-b.git
 * [new branch]      master -> master

or rename it to main first, then push:

$ git branch -M main
$ git branch --show-current
main
$ git push -u origin main
branch 'main' set up to track 'origin/main'.
To ../remote-c.git
 * [new branch]      main -> main

After each fix, git ls-remote --heads origin listed exactly one branch on the remote, with the name that was pushed. Which of the two master fixes to use depends on the name the team and the remote expect: pushing master publishes it under its current name, and the rename makes the remote's first branch main. The capital -M renames even if a branch called main already exists, so check git branch first in an older repository.

How it was reproduced

Git for Windows 2.45.2 (git version 2.45.2.windows.1) in Git Bash 5.2.26. Three local bare repositories made with git init --bare stood in for GitHub, so the To lines show ../remote.git where you would see your remote's URL. Case one was git init -b main, a README that was never committed and git push -u origin main. Cases two and three were a plain git init (master, from the system config), one commit, and the same push. The personal global config was replaced by an empty file (GIT_CONFIG_GLOBAL) so no personal setting could change the result.

Frequently asked

What does 'src refspec main does not match any' mean in Git?
Git cannot find a local branch called main to push. Either the repository has no commits yet, so main does not exist, or the current branch has another name, such as master.
How do I fix src refspec main does not match any after git init?
Make the first commit with git add and git commit, then run git push -u origin main again. A branch only exists once it points at a commit.
Should I push master or rename it to main?
Either works. git push -u origin master publishes the branch under its current name. git branch -M main renames it locally first, so the remote gets main. Use the name your team and the remote expect.

More decoded errors in the Fixes category. The message most people meet next, on the first push of a second branch: the current branch has no upstream branch.