[Git] Error: failed to push some refs — non-fast-forward updates were rejected — How to Fix It
Summary
The Git error error: failed to push some refs — non-fast-forward updates were rejected occurs when your local branch history diverges from the remote branch. Git blocks the push to avoid overwriting commits that exist remotely but not locally. The fix is to synchronize histories first using git pull --rebase origin main or git pull origin main, and only force push if you fully understand the implications.
Context
A “non–fast-forward” rejection happens when the remote branch contains commits that your local branch doesn’t have. Git uses fast-forward pushes only when your branch tip can directly advance the remote’s history. If you’ve rebased, amended, or reset commits, the history no longer matches, and Git refuses to update the remote to prevent data loss. This is common in collaborative workflows where multiple people push to the same branch. It can occur across all platforms — Windows, macOS, Linux — or via Git clients like VS Code, GitHub Desktop, or Git Bash.
Probable Cause
- The remote branch contains new commits that your local branch does not include.
- Your local branch history was rewritten (via rebase, amend, or reset), creating a mismatch.
- Push protection rules prevent overwriting shared history on the remote.
- Another collaborator pushed updates to the same branch before your push.
Quick Fix
Bring your local branch up to date before pushing again. Choose the safest approach for your situation:
- Check your current branch and pending commits:
git status
- Fetch the latest changes from the remote:
git fetch origin
- Compare your local commits to the remote branch:
git log origin/main..HEAD --oneline # local commits not on remote
git log HEAD..origin/main --oneline # remote commits not in local
- Integrate remote updates:
- Recommended (clean linear history):
git pull --rebase origin main
- Alternative (simpler but adds merge commit):
git pull origin main
- Resolve conflicts if prompted, stage the resolutions, and continue:
git add .
git rebase --continue
- Push again once your history matches the remote:
git push origin main
- If you intentionally want to overwrite remote history (use with caution):
git push --force origin main
Full Example
A developer tries to push their changes:
git push origin main
Git rejects the push:
error: failed to push some refs to 'https://github.com/user/repo.git'
hint: Updates were rejected because the tip of your current branch is behind its remote counterpart.
They fetch and inspect differences:
git fetch origin
git log HEAD..origin/main --oneline
After verifying the remote has new commits, they rebase and push successfully:
git pull --rebase origin main
git push origin main
If the branch was private and the user wanted to overwrite it intentionally, they could use:
git push --force origin main
After this, the push completes, and the remote reflects the updated history.
Pitfalls & Debug
- Symptom: Push rejected repeatedly → Fix: Ensure you’re pushing to the correct remote branch with
git branch -vv. - Symptom: Conflicts during rebase → Fix: Resolve manually, then
git rebase --continue. - Symptom: “Non-fast-forward” after amend → Fix: Use
git push --force-with-leaseto safely update. - Symptom: Shared branch protections block force push → Fix: Contact repo maintainer or use a pull request instead.
- Symptom: Accidentally lost commits → Fix: Recover with
git reflogand restore from previous state.
Validation & Next Steps
Confirm your branch is fully synchronized with the remote:
git fetch --all
git status
It should show “Your branch is up to date with 'origin/main'.” For visual verification:
git log --graph --oneline --all
Always pull or rebase before pushing to reduce divergence and minimize non–fast-forward rejections.
Sources
Git documentation — git-push
Pro Git Book — Remote repositories and fast-forward merges
Stack Overflow — “non-fast-forward push rejected” troubleshooting threads
Atlassian Git tutorials — Rebasing vs merging explained