Table of Contents
- Overview
- Quickstart (most fixes in minutes)
- Minimal working example: push with a PAT non-interactively (Bash)
- Configure a credential helper (persistent, secure)
- Clear bad cached credentials
- Verify token scopes (common hosts)
- Check and fix your remote URL and identity
- Debugging: see why auth fails
- CI/CD usage (non-interactive)
- Common pitfalls
- Performance and reliability notes
- Step-by-step fix checklist
- Tiny FAQ
Overview
If you see fatal: Authentication failed when pushing over HTTPS, your credentials were rejected by the remote. Common causes:
- Using a password instead of a Personal Access Token (PAT)
- Wrong or expired token, missing scopes, or SSO not authorized
- Stale cached credentials in a credential helper
- Incorrect remote URL or username
- Corporate proxies or TLS interception breaking auth
This guide shows practical, fast fixes for Git over HTTPS in typical DevOps workflows.
Quickstart (most fixes in minutes)
- Verify the remote URL is HTTPS and correct:
- git remote -v should show https://host/owner/repo.git
- Use a Personal Access Token (PAT) instead of your password.
- If your account has 2FA/SAML SSO, passwords won’t work; PATs (or SSH) are required.
- Clear bad cached credentials and re-authenticate.
- Ensure the credential helper is set for your OS.
- Confirm PAT scopes allow pushing.
- Try the push again, adding debug if needed.
Minimal working example: push with a PAT non-interactively (Bash)
This works on Linux/macOS with base64 available and avoids storing the token.
# Set your username and a valid PAT for the host.
export GIT_USER="your-username"
export GIT_PAT="your-personal-access-token"
# Ensure the remote URL is correct and HTTPS.
REPO_URL="https://github.com/owner/repo.git" # adjust host/owner/repo
git remote set-url origin "$REPO_URL"
# One-off push using an Authorization header (no prompt, no storage):
# Note: Basic auth header is user:token base64-encoded.
BASIC=$(printf "%s:%s" "$GIT_USER" "$GIT_PAT" | base64)
git -c http.extraHeader="Authorization: Basic $BASIC" push origin HEAD:main
If this succeeds, your token and URL are correct. Next, set a credential helper so you don’t need the header each time.
Configure a credential helper (persistent, secure)
- Windows: git config --global credential.helper manager-core
- macOS: git config --global credential.helper osxkeychain
- Linux (GNOME/libsecret): git config --global credential.helper libsecret
- Cross-platform (if installed): git config --global credential.helper manager-core
After configuring, push normally:
git push origin HEAD:main
# When prompted: username = your account; password = your PAT
Clear bad cached credentials
If a helper has stale creds, clear them and retry.
- Generic (specify host):
# Remove stored credential for a host
printf "protocol=https\nhost=github.com\n" | git credential reject
- Remove all configured helpers (then reconfigure one):
git config --global --unset-all credential.helper || true
# Re-add the right helper
git config --global credential.helper manager-core # or osxkeychain/libsecret
- You can also delete entries via your OS credential manager/keychain UI if needed.
Verify token scopes (common hosts)
- GitHub: repo (for private) or public_repo (public only). If org uses SAML SSO, authorize the token for that org.
- GitLab: write_repository (push), read_repository (fetch).
- Azure DevOps: Code (Read & Write) scope for the project/organization.
If scopes are wrong or token expired, create a new PAT with the correct scopes.
Check and fix your remote URL and identity
# Show remotes
git remote -v
# Example correct HTTPS format
# https://github.com/owner/repo.git
# https://gitlab.com/group/project.git
# https://dev.azure.com/org/project/_git/repo
# Fix a wrong remote
git remote set-url origin https://HOST/OWNER/REPO.git
# Ensure your Git identity is set (not used for auth but good practice)
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
Note: For GitHub, the username is your account handle; the password prompt expects your PAT (not your account password).
Debugging: see why auth fails
# Add verbose curl/http tracing for one command
GIT_TRACE=1 GIT_CURL_VERBOSE=1 git push origin HEAD:main
Look for HTTP/401 (Unauthorized), 403 (Forbidden), or proxy/TLS errors. 401 suggests bad or missing creds; 403 suggests insufficient scopes or SSO.
CI/CD usage (non-interactive)
- Store PAT in a secret variable, e.g., GIT_PAT.
- Use the extraHeader technique or a credential helper pre-seeded by the runner.
# CI-friendly push (no prompt)
BASIC=$(printf "%s:%s" "$GIT_USER" "$GIT_PAT" | base64)
git -c http.extraHeader="Authorization: Basic $BASIC" push origin "$CI_COMMIT_SHA":refs/heads/main
Avoid embedding tokens in remotes (https://user:token@host) as they can leak via logs and config.
Common pitfalls
- Using account password on hosts that removed password auth for Git over HTTPS
- Token missing write scope, or SSO/SAML not authorized for the token
- Stale credentials cached by manager-core/osxkeychain/libsecret
- Wrong username (case-sensitive on some hosts) or ownership mismatch
- Submodules with their own HTTPS URLs still pointing to old/bad creds
- Corporate proxy MITM replacing the certificate; install the corporate CA for Git/cURL or use SSH
- Using http (not https) or an outdated redirecting URL breaking auth headers
Performance and reliability notes
- Configure a credential helper to avoid repeated auth round-trips and prompts.
- Prefer PAT + helper over embedding tokens in remotes; reduces accidental leaks and makes rotation safer.
- If your network adds latency, a helper plus HTTP/2 (default in modern Git/cURL) reduces repeated auth negotiations.
- For large repos, pushing less often with batched commits doesn’t change auth, but reduces total HTTPS negotiations.
- Consider SSH for long-lived automation to avoid HTTPS token rotation policies.
Step-by-step fix checklist
- git remote -v and correct the URL if needed.
- Generate a PAT with push/write scope; ensure SSO is authorized where required.
- Clear cached creds for the host; set the appropriate credential helper.
- Push once; when prompted, use username + PAT. Or use the extraHeader one-off method.
- If it still fails, run with GIT_TRACE=1 GIT_CURL_VERBOSE=1 and inspect HTTP status and host.
- Check proxies/CA and submodule remotes. Update as needed.
Tiny FAQ
Q: Why doesn’t my password work anymore?
- A: Most hosts removed password auth for Git over HTTPS. Use a PAT or SSH.
Q: I have 2FA. What do I enter at the password prompt?
- A: Enter your PAT, not your account password.
Q: Do I need to include my PAT in the remote URL?
- A: No. Use a credential helper or the extraHeader method for CI.
Q: I get 403 Forbidden, not 401. What does that mean?
- A: Your token is valid but lacks scope (or SSO not authorized). Fix scopes/SSO.
Q: Can I switch to SSH to avoid HTTPS auth?
- A: Yes. Add your SSH key to the host and set the remote to an ssh:// or git@ URL.