Photo by Bernd ๐ท Dittrich on Unsplash
So there I was, trying to push an image to Docker Hub at some ungodly hour before a production deploy, and I get hit with this:
Error response from daemon: Get "https://registry-1.docker.io/v2/":
unauthorized: incorrect username or password
Password's correct. I just logged into Docker Hub in my browser two minutes ago. And yet, here we are. The Docker login authentication error is one of those things that seems stupidly simple on the surface but can actually have like four or five completely different root causes. I've seen it trip up junior devs and senior engineers alike, so don't feel bad if you're sitting here scratching your head.
Let me walk you through what I've found actually works.
Why This Error Even Happens
Before we start throwing fixes at the wall, it helps to understand what's going on. When you run docker login, Docker doesn't just check your credentials and move on — it stores an authentication token in a credentials store on your machine. On macOS, that's your Keychain. On Windows, it uses Windows Credential Manager. On Linux, it depends on what you've got configured, which is honestly where most of the chaos lives.
The error shows up most often because of one of three things: your stored credentials are stale or corrupted, your credentials helper is misconfigured or missing, or (and this one gets people all the time) Docker Hub switched you to a personal access token requirement and you're still using your plain password.
Fix #1: Log Out, Nuke the Config, Log Back In
This is the "turn it off and on again" of Docker auth fixes — and honestly, it works more often than it should. Stale tokens are a surprisingly common culprit.
docker logout
Then manually clear out the stored credentials config:
# On Linux/macOS
rm ~/.docker/config.json
# Then log back in fresh
docker login
Worth noting: config.json stores more than just auth tokens — it can have proxy settings and other stuff — so if you've got a custom config, maybe back it up first with a quick cp ~/.docker/config.json ~/.docker/config.json.bak before you delete anything.
If that clears it, great. If not, keep reading.
Fix #2: Fix the Credentials Helper Issue
Here's the thing though — this is actually the most common cause on Linux systems, and it's weirdly under-documented. Open up your ~/.docker/config.json and you might see something like this:
{
"credsStore": "desktop",
"auths": {}
}
That "credsStore": "desktop" line is the problem. It's pointing to Docker Desktop's credential helper, which either isn't installed or isn't running — especially common if you migrated from Docker Desktop to plain Docker Engine on Linux. Docker's trying to look up credentials in a helper that doesn't exist, and it fails silently in the worst way.
The fix: either remove that line entirely from your config, or switch it to a helper that's actually installed. If you just want things to work quickly, remove the credsStore entry:
# Open the file
nano ~/.docker/config.json
# Remove or comment out the credsStore line, save, then:
docker login
If you want to do it properly and use a real credentials helper, install docker-credential-helpers for your platform. On Linux:
sudo apt install golang-docker-credential-helpers
# or download the binary directly from GitHub releases for your distro
Then update your config.json to use pass or secretservice depending on your setup. This is the more robust long-term solution if you're running a CI server or remote machine.
Fix #3: Use a Personal Access Token Instead of Your Password
This one trips people up because Docker Hub changed their authentication requirements and not everyone got the memo. If you've got two-factor authentication enabled on Docker Hub — or if you're logging in from a CI/CD pipeline — plain passwords are no longer supported. You need a Personal Access Token (PAT).
Go to Docker Hub → Account Settings → Security → New Access Token. Generate one, copy it, and then use it as your password when logging in:
docker login -u your_username
# When prompted for password, paste your PAT instead
Or do it non-interactively (useful for scripts and pipelines):
echo "your_pat_here" | docker login -u your_username --password-stdin
The --password-stdin flag is the correct way to do it in automation — piping it in avoids the token showing up in your shell history, which matters if you care about security. And you should.
I've set up probably dozens of GitHub Actions workflows at this point, and nine times out of ten when someone's CI pipeline is throwing a Docker registry authentication error, it's because they stored their actual Docker Hub password as a secret instead of a PAT. Generate the token, update your secret, done.
Fallback: Check If Docker Daemon Is Actually Running
Okay, this sounds embarrassing but just humor me for a second. Sometimes the "authentication error" is masking a totally different problem — the Docker daemon isn't running, so literally nothing works and the error messaging is just bad.
sudo systemctl status docker
If it's not active, start it:
sudo systemctl start docker
Also worth running a quick sanity check to make sure your user is in the docker group, because permission issues can sometimes surface as auth errors:
groups $USER | grep docker
If docker's not in there, add yourself and reload:
sudo usermod -aG docker $USER
newgrp docker
In my experience, the credentials helper fix (Fix #2) solves this for the majority of Linux users, while the PAT fix is almost always the answer for anyone hitting this in a CI/CD context. The log-out-and-back-in approach is just good first-step hygiene regardless.
Hope this saves you an hour of frustrated Googling. Go push that image.
Related: How to Fix Docker Error Getting Credentials (And Why It Keeps Happening)
๋๊ธ
๋๊ธ ์ฐ๊ธฐ