Skip to content

Fix: Git Keeps Asking for Username and Password

FixDevs · (Updated: )

Part of:  Docker, DevOps & Infrastructure

Quick Answer

How to fix Git repeatedly prompting for credentials — credential helper not configured, HTTPS vs SSH, expired tokens, macOS keychain issues, and setting up a Personal Access Token.

The Error

Every git push, git pull, or git fetch prompts for credentials:

Username for 'https://github.com': yourusername
Password for 'https://[email protected]':

Or after entering credentials once, Git asks again on the next command. Or you get an authentication failure even after entering the correct password:

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories for information on currently supported authentication methods.
fatal: Authentication failed for 'https://github.com/user/repo.git'

Or Git was working before but suddenly asks for credentials again after a system update or password change.

Why This Happens

Git does not store credentials anywhere by itself. Every HTTPS push, pull, or fetch is a fresh HTTP request, and Git has no concept of a session. Authentication is delegated entirely to a credential helper — a small external program that Git invokes with get, store, or erase commands. If no helper is configured, Git falls back to prompting on stdin every time. If a helper is configured but cannot find a matching credential, you get the same prompt.

The credential model also has a strict matching rule. Helpers look up credentials by protocol + host + path (path matching is optional). If the URL Git sends to the helper does not exactly match the one used during the original store, the helper returns nothing and Git prompts again. Subtle differences — a trailing slash, a port number, a mixed-case hostname — can cause silent re-prompts. Setting credential.useHttpPath = true enables path-specific credentials, which helps when you need separate identities for different repos on the same host.

The third major reason is platform-specific helper drift. Each operating system has shipped a different default helper, and that default has changed over time:

  • No credential helper configuredgit config credential.helper is empty, so Git can’t save or retrieve credentials.
  • GitHub removed password authentication — GitHub stopped accepting account passwords for HTTPS Git operations in 2021. You must use a Personal Access Token (PAT) instead.
  • Expired PAT or SSH key — credentials are stored but the token has expired or the SSH key was revoked.
  • Wrong remote URL — the remote URL uses HTTPS when SSH is expected (or vice versa), causing the wrong authentication method.
  • macOS Keychain has stale credentials — Git uses the macOS Keychain helper by default, but stored credentials may be outdated or corrupt.
  • HTTPS proxy or corporate network — network changes (VPN, proxy) can cause credential lookups to fail even when credentials are stored.

Version History That Changes the Failure Mode

The credential helper landscape has consolidated significantly. Before 2020, Windows and macOS each had their own bespoke helper. Windows used Git Credential Manager for Windows (often abbreviated GCM-for-Windows), a .NET Framework tool maintained by Microsoft. macOS used git-credential-osxkeychain, a small native helper that talked to the system Keychain. Linux had cache (in-memory) and store (plaintext) and not much else.

In 2020 Microsoft released Git Credential Manager Core (later renamed simply Git Credential Manager, GCM 2.x), a cross-platform .NET 6/8 tool that unified Windows, macOS, and Linux credential storage and added native OAuth 2.0 flows for GitHub, GitLab, Bitbucket, and Azure DevOps. Git for Windows 2.29 (October 2020) replaced the old GCM-for-Windows with GCM Core as the default helper. macOS got GCM as an optional install via Homebrew. The Linux story is messier because there is no system-wide secret store; GCM supports gpg-encrypted files, libsecret (GNOME Keyring), and plaintext as fallbacks.

The bigger external event was GitHub’s August 13, 2021 deprecation of password authentication for HTTPS Git operations. After that date, every HTTPS push to GitHub requires a Personal Access Token (PAT), a fine-grained PAT (introduced in 2022), an OAuth token from GCM, or SSH. Tutorials written before mid-2021 instruct you to “enter your GitHub password,” which produces the remote: Support for password authentication was removed error you see today. GCM 2.x’s OAuth flow opens a browser, stores a short-lived OAuth token in your platform’s secret store, and refreshes it automatically — the only modern way to push to GitHub over HTTPS without managing PAT rotation yourself. Bitbucket Cloud followed with app passwords, and GitLab requires personal access tokens with read_repository/write_repository scopes.

Fix 1: Configure a Credential Helper

The credential helper tells Git where to store and retrieve credentials so it doesn’t ask every time.

macOS — use the built-in Keychain:

git config --global credential.helper osxkeychain

Windows — use Git Credential Manager:

git config --global credential.helper manager
# Or for older Git for Windows:
git config --global credential.helper wincred

Linux — cache credentials in memory:

# Cache for 15 minutes (900 seconds)
git config --global credential.helper cache

# Cache for 8 hours
git config --global credential.helper 'cache --timeout=28800'

Linux — store credentials permanently on disk:

# Stores credentials in plaintext at ~/.git-credentials (less secure)
git config --global credential.helper store

Verify the credential helper is set:

git config --global credential.helper
# Should output: osxkeychain (mac), manager (windows), cache/store (linux)

After setting the helper, the next time Git asks for credentials, enter them once — they’ll be saved and reused automatically.

Fix 2: Use a Personal Access Token (GitHub/GitLab/Bitbucket)

GitHub, GitLab, and most modern Git hosts no longer accept your account password for HTTPS Git operations. You need a Personal Access Token (PAT):

GitHub — create a PAT:

  1. Go to GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
  2. Click “Generate new token (classic)”
  3. Select scopes: repo (for private repos), read:org if needed
  4. Copy the token immediately — it’s only shown once

Use the PAT as your password:

# When Git prompts for credentials:
Username: your-github-username
Password: ghp_xxxxxxxxxxxxxxxxxxxx Paste your PAT here, not your account password

Or embed the PAT directly in the remote URL (not recommended for shared machines):

git remote set-url origin https://your-username:[email protected]/user/repo.git

Warning: Embedding a PAT in the remote URL stores it in .git/config in plaintext. Anyone with access to the repo directory can read it. Use a credential helper instead.

GitLab — create an access token:

  1. Profile → Preferences → Access Tokens
  2. Create token with read_repository and write_repository scopes

Bitbucket — create an app password:

  1. Account settings → App passwords → Create app password
  2. Select Repository read/write permissions

Fix 3: Switch from HTTPS to SSH

SSH authentication doesn’t require a password every time (once your SSH key is loaded into the agent). Switching to SSH eliminates credential prompts entirely:

Generate an SSH key if you don’t have one:

# Generate a new SSH key (Ed25519 is recommended)
ssh-keygen -t ed25519 -C "[email protected]"

# Default location: ~/.ssh/id_ed25519 (private key) and ~/.ssh/id_ed25519.pub (public key)

Add the public key to your Git host:

# Copy the public key
cat ~/.ssh/id_ed25519.pub
# Paste this into GitHub → Settings → SSH and GPG keys → New SSH key

Test the SSH connection:

ssh -T [email protected]
# Hi username! You've successfully authenticated, but GitHub does not provide shell access.

Switch the remote from HTTPS to SSH:

# Check current remote URL
git remote -v
# origin  https://github.com/user/repo.git (fetch)

# Switch to SSH
git remote set-url origin [email protected]:user/repo.git

# Verify
git remote -v
# origin  [email protected]:user/repo.git (fetch)

Start the SSH agent and add your key:

# Start ssh-agent
eval "$(ssh-agent -s)"

# Add your private key
ssh-add ~/.ssh/id_ed25519

# On macOS — add to Keychain permanently
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Configure SSH to use your key automatically (add to ~/.ssh/config):

Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519
    AddKeysToAgent yes
    UseKeychain yes    # macOS only

Fix 4: Fix macOS Keychain Stale Credentials

If you changed your GitHub password or PAT, the macOS Keychain may still have the old credentials. Git will fail silently using the stale data:

# Remove stale credentials from Keychain
git credential-osxkeychain erase
host=github.com
protocol=https
# Press Enter, then Ctrl+D

# Or use the Keychain Access app (macOS):
# Search for "github.com" → delete the entry → Git will prompt for new credentials

Or reset via the macOS CLI:

# List keychain entries for github.com
security find-internet-password -s github.com

# Delete the stored credentials
security delete-internet-password -s github.com

Force Git to re-authenticate:

# Clear stored credentials and re-enter
git credential reject <<EOF
protocol=https
host=github.com
EOF

# On next git push/pull, Git will prompt for credentials and save them fresh

Fix 5: Fix Git Credential Manager (Windows/Cross-platform)

Git Credential Manager (GCM) is the recommended helper for Windows and cross-platform setups:

# Check if GCM is installed
git credential-manager --version

# Install GCM (if not installed)
# macOS via Homebrew:
brew install --cask git-credential-manager

# Windows — included with Git for Windows
# Linux — see https://github.com/git-ecosystem/git-credential-manager
# Configure Git to use GCM
git config --global credential.helper manager

# Clear a cached credential
git credential-manager github logout

GCM supports GitHub OAuth (no PAT needed):

# After configuring GCM, the first git push will open a browser for OAuth login
git push origin main
# → Opens browser → Authorize Git Credential Manager → Credentials saved

Fix 6: Configure Per-Repository Credentials

If you use multiple accounts (personal and work), set credentials per repository instead of globally:

# In the repository directory (not --global)
git config credential.helper store

# Or set the URL with credentials embedded (use carefully)
git remote set-url origin https://[email protected]/company/repo.git
# Git will only prompt for the password for this specific host/username combination

Use SSH with multiple accounts:

# ~/.ssh/config
Host github-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal

Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
# Personal repo — use github-personal host alias
git remote set-url origin git@github-personal:personal-user/repo.git

# Work repo — use github-work host alias
git remote set-url origin git@github-work:company/repo.git

Still Not Working?

Check the global Git config to see what credential helper is set:

git config --global --list | grep credential
# credential.helper=osxkeychain  (or manager, cache, store)

Check if a local repo config overrides the global:

git config --local --list | grep credential
# If credential.helper= (empty string), it disables the global helper

An empty credential.helper= in local config disables the global helper. Fix it:

# Remove the local override
git config --local --unset credential.helper

# Or explicitly set it to the global helper
git config --local credential.helper osxkeychain

Check the remote URL format — mixing HTTPS and SSH causes confusion:

git remote -v
# If it shows https:// → use PAT or credential helper
# If it shows git@ → use SSH key

For corporate environments with NTLM/Kerberos authentication:

# Use Git Credential Manager which handles Windows authentication natively
git config --global credential.helper manager

# Or configure the http proxy
git config --global http.proxy http://proxy.company.com:8080

Enable trace logging to see what the helper actually returns. Git ships with built-in tracing that prints every helper invocation and its output:

GIT_TRACE=1 GIT_CURL_VERBOSE=1 GCM_TRACE=1 git push 2>&1 | less

The output shows which helper Git called, which URL it queried, and whether the helper returned a credential or asked for input. If the helper returns no output, the lookup key did not match what was stored.

Check for multiple helpers stacked accidentally. Running git config --global credential.helper manager twice can append two entries instead of replacing one. List them with git config --global --get-all credential.helper. If you see two, unset and set fresh:

git config --global --unset-all credential.helper
git config --global credential.helper manager

Verify the system-level git config. On Windows and macOS, Git for Windows and the Apple Git binary both write a system-level config (/etc/gitconfig or C:\Program Files\Git\etc\gitconfig) that may pin a helper you do not want. git config --system --list | grep credential shows it. You can override at the global level, but the cleanest fix is to remove the system entry if you control the machine.

For related Git authentication issues, see Fix: Git Permission Denied (publickey), Fix: Git Push Rejected Non-Fast-Forward, Fix: Fatal Not a Git Repository, and Fix: Git Remote Origin Already Exists.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles