Fix 'Authentication failed' when pushing to GitHub
Git keeps saying authentication failed even though my password is correct — why?
Short answer
GitHub stopped accepting account passwords over HTTPS in August 2021. You need a personal access token in place of the password, or better, switch the remote to SSH. If it worked yesterday, a cached old credential is usually the culprit — clear it and re-authenticate.
git remote set-url origin git@github.com:USER/REPO.git
Switch to SSH and stop dealing with tokens entirely
Does this match your situation?
- 'remote: Support for password authentication was removed on August 13, 2021.'
- 'fatal: Authentication failed for https://github.com/...'
- Your password is definitely right but Git rejects it.
- It worked until you changed your password or the token expired.
Step-by-step fix
Check which protocol you're using
An https:// URL authenticates with a token; a git@ URL authenticates with an SSH key. The fix is completely different for each, so establish this first.
step 1git remote -vOption A — switch to SSH (recommended)
SSH keys don't expire, don't need rotating, and never prompt again once set up. Generate a key, add the public half to GitHub, then repoint the remote.
step 2ssh-keygen -t ed25519 -C "you@example.com" # press Enter through the prompts # copy the PUBLIC key and paste it at github.com/settings/keys cat ~/.ssh/id_ed25519.pub ssh -T git@github.com # verify it works git remote set-url origin git@github.com:USER/REPO.gitShow the PowerShell (Windows) version
PowerShell (Windows)ssh-keygen -t ed25519 -C "you@example.com" Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | Set-Clipboard # paste at github.com/settings/keys ssh -T git@github.com git remote set-url origin git@github.com:USER/REPO.gitOption B — use a personal access token
If you must stay on HTTPS, create a token and use it wherever Git asks for a password. Fine-grained tokens are scoped to specific repositories and are the safer choice.
step 3# github.com/settings/tokens -> generate a token with 'repo' scope # then push, and paste the TOKEN as the password: git push # Username: your-github-username # Password: ghp_xxxxxxxxxxxxxxxxxxxxCopy the token immediately — GitHub shows it exactly once.
Clear the stale credential that's being reused
This is the step people miss. Your credential helper cached the old password and keeps sending it without asking you, so nothing you type makes any difference until it's cleared.
step 4# Git Credential Manager git credential-manager erase # macOS keychain git credential-osxkeychain erase host=github.com protocol=https # Windows: Control Panel -> Credential Manager -> Windows Credentials # -> remove git:https://github.com
Why this works
Account passwords were removed as a Git credential because a leaked password compromises everything you own, whereas a token can be scoped to one repository and revoked independently. The confusing part is the credential helper: it stores the first credential that works and replays it silently forever, so once a token expires or is revoked you get authentication failures that seem impervious to typing the right thing. Clearing the stored credential is what makes Git ask again.
If that didn’t work
- Confirm the token hasn't expired and has the repo scope at github.com/settings/tokens.
- For an organisation repo, check whether SSO authorisation is required for the token.
- Test SSH explicitly: ssh -vT git@github.com shows exactly which key is offered.
- If port 22 is blocked on your network, use SSH over HTTPS: set the host to ssh.github.com port 443 in ~/.ssh/config.
How to stop it happening again
- Use SSH keys — set up once, never expire, no rotation.
- If you use tokens, note the expiry date somewhere you'll see it.
- Configure a credential helper backed by your OS keychain rather than plaintext storage.
Commands used in this guide
Still stuck?
Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.
Browse all guides →Frequently asked questions
Why does GitHub reject my correct password?
GitHub removed password authentication for Git operations on 13 August 2021. Your account password still works for the website, but Git over HTTPS now requires a personal access token instead — or an SSH key, which avoids the issue entirely.
Should I use SSH or a personal access token?
SSH for your own machines: keys don't expire, so it's set-and-forget. Tokens are better for CI, scripts and shared environments, where you want a credential that is scoped narrowly and can be revoked without touching anything else.
I created a new token but Git still fails. Why?
Your credential helper is still replaying the old one and never prompts you. Clear the stored credential for github.com — via git credential-manager erase, the macOS Keychain, or Windows Credential Manager — and Git will ask again on the next push.
Related rescue guides
git clone or push fails with Permission denied (publickey) — how do I fix my SSH key?
The server didn't accept any key your SSH client offered. Either you have no key, the key isn't loaded into the agent, or its public half was never added to your account. Run ssh -T git@github.com to see exactly which keys are being tried.
Read the fix →Always fixableHow do I make Git remember my credentials?
Configure a credential helper that stores the token in your OS keychain, or switch to SSH keys and skip credentials entirely. Avoid the `store` helper — it writes your token to a plaintext file.
Read the fix →Always fixableHow do I change the remote URL of a Git repository?
git remote set-url origin <new-url> repoints an existing remote. It's a purely local change — nothing on either server is touched — so it's the safe way to switch between HTTPS and SSH, move to a new host, or fix a URL after renaming the repository.
Read the fix →Always fixableMy push was rejected — 'Updates were rejected because the remote contains work that you do not have'. What now?
Someone pushed commits you don't have yet, so your push would erase them. Git is protecting you. Fetch and integrate their work first with git pull --rebase, then push again. Never reach for --force here unless you genuinely intend to delete what's on the server.
Read the fix →