Photo by Arnold Francisca on Unsplash
So I was setting up a new dev machine at like 11pm, running docker push to get an image up to Docker Hub, and I get hit with this:
Error saving credentials: error storing credentials - err: exit status 1,
out: `credentials store not initialized`
Awesome. Really love seeing that after a long day. The Docker credential helper configuration had gone sideways somewhere between installing Docker Desktop and setting up my config manually. And honestly, this is one of those errors that looks scarier than it is — but it can also send you down some weird rabbit holes if you don't know what's actually going on.
Let me explain what's happening and how to get past it.
Why This Happens in the First Place
Docker uses a credential helper system to store your registry login info securely — instead of just dumping your password in plain text inside ~/.docker/config.json (which, yes, was a thing). The credential helper offloads that to your OS keychain or a dedicated secrets manager like pass on Linux or wincred on Windows.
The problem shows up when your config.json is pointing to a credential store that either doesn't exist, hasn't been initialized, or flat-out isn't installed. This happens a lot when you:
- Install Docker Engine on Linux without Docker Desktop (which would normally handle this for you)
- Copy a config file from another machine
- Upgrade Docker and something gets reset
- Set up a CI/CD environment and wonder why credentials aren't persisting
I've seen this a hundred times on fresh Ubuntu servers especially. The config file exists but the helper binary it's referencing is just... not there.
Here's what a broken ~/.docker/config.json typically looks like:
{
"credsStore": "desktop-linux"
}
That credsStore value is telling Docker to use docker-credential-desktop-linux — which only exists if you have Docker Desktop installed. If you're on a headless server or stripped-down environment, that binary doesn't exist and Docker just throws its hands up.
Fix 1: Remove or Update the credsStore Entry
The fastest fix — and honestly what solves it 80% of the time — is to just edit your config.json and either remove the credsStore line or replace it with something that actually exists on your system.
nano ~/.docker/config.json
If you're okay with Docker falling back to base64-encoded credentials stored in the config file itself (totally fine for personal machines or isolated environments), just delete the credsStore line entirely. Your file should look something like:
{
"auths": {}
}
Then run docker login again. It'll store your credentials locally in that file. Not the most secure option for production, but it works and it stops the error cold.
Fix 2: Install the Correct Credential Helper Binary
If you actually want the secure credential storage (and you probably should in any shared or production environment), you need to install the right helper. On Linux, docker-credential-pass is the most common one people use.
First, grab the binary from the GitHub releases page or install it directly:
# Check latest version at https://github.com/docker/docker-credential-helpers/releases
VERSION=0.8.1
curl -fsSL "https://github.com/docker/docker-credential-helpers/releases/download/v${VERSION}/docker-credential-pass-v${VERSION}.linux-amd64" \
-o /usr/local/bin/docker-credential-pass
chmod +x /usr/local/bin/docker-credential-pass
Now here's where it gets tricky — pass itself needs to be initialized with a GPG key before the credential helper can actually use it. A lot of people install the binary and then wonder why it's still broken.
# Install pass
sudo apt-get install pass gpg
# Generate a GPG key if you don't have one
gpg --gen-key
# Initialize pass with your GPG key ID
pass init YOUR_GPG_KEY_ID
You can find your GPG key ID by running gpg --list-keys and grabbing the long hex string. Once that's done, update your config.json:
{
"credsStore": "pass"
}
Run docker login and you should be good. The credentials will be stored encrypted via your GPG key. Much cleaner.
Fix 3: Use the osxkeychain or wincred Helper on Mac/Windows
If you're on macOS and hitting this issue, it's usually because the osxkeychain helper got disconnected somehow — often after a Docker Desktop update or a migration.
# Verify the helper exists
which docker-credential-osxkeychain
# If it's there, just update your config.json
{
"credsStore": "osxkeychain"
}
On Windows with Docker Desktop, it should use wincred or desktop-windows automatically. If you've somehow got a mismatched value in there (I've seen people copy Linux configs onto Windows machines — don't do that), just reset it:
{
"credsStore": "wincred"
}
And then re-run docker login to re-authenticate.
Fallback: Nuke the Config and Start Fresh
Sometimes the config file is just mangled enough that it's easier to start from scratch. This is especially true if you've got weird key conflicts or invalid JSON hanging around in there.
mv ~/.docker/config.json ~/.docker/config.json.bak
docker login
Docker will recreate the config file fresh. You'll lose any saved auth tokens but that's honestly not a big deal — just log back in to your registries. I usually keep the backup around for like a day just in case, then delete it.
One thing worth mentioning — if you're doing this in a Dockerfile or CI pipeline context, you probably don't want credential helpers at all. Just use environment variables or a secrets manager and pass credentials at build/run time. Baking credential helper config into a container image is a headache I wouldn't wish on anyone.
Anyway, hope this saves you the hour I lost staring at that error the first time I saw it. The Docker credential helper system is genuinely useful once it's set up right — it just has almost zero helpful error messaging when something's off.
Related: How to Fix Docker Error Getting Credentials (And Why It Keeps Happening)
๋๊ธ
๋๊ธ ์ฐ๊ธฐ