How to fix ! [rejected] main -> main (non-fast-forward) error: failed to push some refs in Git

GitBEGINNERLOWUpdated Dec 6, 2025· 264 views

This error occurs when the remote branch has commits that your local branch doesn't have. Git refuses the push to prevent overwriting those commits. The solution is to fetch and integrate the remote changes before pushing.

Quick fix

Fixes ! [rejected] main -> main (non-fast-forward) error: failed to push some refs

git fetch origin
  1. Fetch the latest changes from remote
  2. View what's different between local and remote
  3. Integrate remote changes (Option A: Merge)
  4. Integrate remote changes (Option B: Rebase)
git — error
git fetch origin
! [rejected] main -> main (non-fast-forward) error: failed to push some refs

What this error means

When you try to push commits to a remote repository, Git checks whether your push is a "fast-forward" update. A fast-forward means your new commits can simply be appended to the remote branch without losing any history. A non-fast-forward push means the remote branch has diverged from your local branch—someone else has pushed commits that you don't have locally. If Git allowed your push, those commits would be lost forever. This is why Git rejects the push with the "non-fast-forward" error. This commonly happens when: - A teammate pushed changes to the same branch while you were working - You rebased or amended commits that were already pushed - You're working on a shared branch without pulling regularly - CI/CD systems or bots have made commits to the branch

Typical symptoms

  • Push fails with '! [rejected] main -> main (non-fast-forward)'
  • Error message mentions 'failed to push some refs'
  • Hint suggests running 'git pull' before pushing
  • Push worked previously but now fails on the same branch
  • Multiple developers working on the same branch experience push failures

Common causes

  1. The remote branch has new commits that aren't in your local branch (most common)
  2. Another developer pushed to the same branch while you were working
  3. You used 'git commit --amend' on a commit that was already pushed
  4. You used 'git rebase' on commits that were already pushed
  5. CI/CD automation pushed commits to the branch
  6. You force-pushed from another machine and your local is now behind

How to fix "! [rejected] main -> main (non-fast-forward) error: failed to push some refs"

1Fetch the latest changes from remote

First, download the remote changes without modifying your working directory:

bash
git fetch origin

This updates your remote-tracking branches (like origin/main) so you can see what's different.

2View what's different between local and remote

Before merging, understand what commits exist on the remote that you don't have:

bash
git log HEAD..origin/main --oneline

This shows commits on origin/main that aren't in your local branch. You can also see a visual comparison:

bash
git log --oneline --graph --all
3Integrate remote changes (Option A: Merge)

The simplest approach is to merge the remote changes into your local branch:

bash
git pull origin main

Or if you've already fetched:

bash
git merge origin/main

This creates a merge commit that combines both histories. If there are conflicts, Git will pause and let you resolve them.

4Integrate remote changes (Option B: Rebase)

For a cleaner, linear history, rebase your commits on top of the remote changes:

bash
git pull --rebase origin main

Or if you've already fetched:

bash
git rebase origin/main

This replays your local commits on top of the remote branch. If there are conflicts, resolve them and run:

bash
git rebase --continue
5Push your changes

After integrating the remote changes, push again:

bash
git push origin main

The push should succeed because your local branch now includes all commits from the remote.

6If you intentionally rewrote history (use with caution)

If you used git commit --amend or git rebase to intentionally modify commits that were already pushed, you may need to force push:

bash
git push --force-with-lease origin main

WARNING: This overwrites the remote branch. Only do this if:
- You're the only one working on this branch, OR
- You've coordinated with your team, OR
- This is your personal fork

The --force-with-lease flag is safer than --force because it fails if someone else pushed in the meantime.

Advanced notes

### Understanding Fast-Forward vs Non-Fast-Forward

A fast-forward update is when the remote branch's tip is an ancestor of your local commits. Git can simply move the remote pointer forward:

bash
Before push:
Remote: A - B - C
Local:  A - B - C - D - E  (fast-forward possible)

After push:
Remote: A - B - C - D - E

A non-fast-forward update means the histories have diverged:

bash
Remote: A - B - C - F - G  (someone else pushed F and G)
Local:  A - B - C - D - E  (you have D and E)

Git refuses because pushing would lose commits F and G.

### Preventing This Error

1. Pull before you start working: git pull at the start of each session
2. Pull before you push: Make it a habit to run git pull --rebase before pushing
3. Use feature branches: Avoid pushing directly to main/master
4. Communicate with your team: Coordinate when multiple people need to push to the same branch

### When Force Push Is Acceptable

Force pushing is generally safe when:
- Working on your own feature branch that no one else uses
- Cleaning up commits before a pull request review
- Fixing a mistake immediately after pushing (before anyone pulled)

It's dangerous when:
- Working on shared branches (main, develop)
- Other developers have based work on your commits
- CI/CD systems are tracking the branch

### CI/CD Considerations

If your CI/CD pipeline commits back to the repository (version bumps, changelog updates, etc.), this can cause non-fast-forward errors. Solutions:
- Have CI push to a different branch
- Always pull before local development
- Use merge commits instead of rebase in CI

Frequently asked questions

What does "! [rejected] main -> main (non-fast-forward) error: failed to push som" mean?
When you try to push commits to a remote repository, Git checks whether your push is a "fast-forward" update. A fast-forward means your new commits can simply be appended to the remote branch without losing any history. A non-fast-forward push means the remote branch has diverged from your local branch—someone else has pushed commits that you don't have locally.
How do I fix "! [rejected] main -> main (non-fast-forward) error: failed to push som"?
This error occurs when the remote branch has commits that your local branch doesn't have. Git refuses the push to prevent overwriting those commits. The solution is to fetch and integrate the remote changes before pushing.
What causes "! [rejected] main -> main (non-fast-forward) error: failed to push som"?
The remote branch has new commits that aren't in your local branch (most common) Another developer pushed to the same branch while you were working You used 'git commit --amend' on a commit that was already pushed
Is the "! [rejected] main -> main (non-fast-forward) error: failed to push som" error serious?
It is a low-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading