The 'Error saving credentials' error occurs when Docker cannot store your login credentials using the configured credential helper. This typically happens due to misconfigured credential helpers, uninitialized password stores, or permission issues with the Docker configuration directory.
This error indicates that Docker's credential storage mechanism failed when trying to save your authentication credentials after a `docker login` command. Docker uses credential helpers to securely store registry credentials, and when these helpers are misconfigured or unavailable, this error occurs. Docker supports multiple credential helpers depending on your operating system: - **macOS**: `docker-credential-osxkeychain` (uses macOS Keychain) - **Windows**: `docker-credential-wincred` (uses Windows Credential Manager) - **Linux**: `docker-credential-secretservice` (uses D-Bus Secret Service) or `docker-credential-pass` (uses the pass password manager) The error can occur in several contexts: 1. **Missing credential helper** - The helper specified in `~/.docker/config.json` is not installed 2. **Uninitialized pass store** - On Linux with docker-credential-pass, the GPG-based password store needs initialization 3. **Permission issues** - Docker cannot write to `~/.docker/config.json` or the credential store 4. **Docker Desktop conflicts** - Installing/uninstalling Docker Desktop can leave orphaned credential helper references 5. **GPG key problems** - The GPG key used for the pass store is missing or corrupted
The most common fix is to remove or correct the credsStore setting in your Docker configuration file.
# View current Docker config
cat ~/.docker/config.jsonIf you see "credsStore": "desktop" or another helper that's not installed, remove it:
# Backup the config first
cp ~/.docker/config.json ~/.docker/config.json.backup
# Edit the config file
nano ~/.docker/config.jsonRemove the entire "credsStore": "something" line. Your config should look like:
{
"auths": {}
}Note: Without a credential helper, Docker will store a base64-encoded token in the config file (less secure but functional). After editing, try docker login again.
Permission issues with the Docker configuration directory can prevent credential storage.
# Fix ownership of the .docker directory
sudo chown -R $(id -u):$(id -g) ~/.docker
# Set correct permissions
chmod 700 ~/.docker
chmod 600 ~/.docker/config.jsonIf you've been mixing sudo and non-sudo Docker commands, you may have root-owned files:
# Check ownership
ls -la ~/.docker/
# If owned by root, fix it
sudo chown -R $USER:$USER ~/.dockerThen try logging in again:
docker loginIf you're using docker-credential-pass on Linux, the pass password store must be initialized with a GPG key.
Step 1: Generate a GPG key (if you don't have one)
# Generate a new GPG key
gpg --generate-key
# Follow the prompts - use your email address
# Note the key ID that's generated (looks like a long hex string)Step 2: List your GPG keys to get the key ID
gpg --list-keys
# Output shows something like:
# pub rsa3072 2024-01-15 [SC]
# ABCD1234EFGH5678IJKL9012MNOP3456QRST7890
# uid [ultimate] Your Name <[email protected]>Step 3: Initialize pass with your GPG key
# Use the key ID or email from above
pass init "[email protected]"
# or
pass init "ABCD1234EFGH5678IJKL9012MNOP3456QRST7890"Step 4: Test Docker login
docker loginImportant: Make sure you're using gpg (not gpg2) or ensure pass is configured to use the correct gpg version.
If credentials are corrupted in the credential store, clearing them can resolve the issue.
For Linux with pass:
# Remove Docker credentials from pass
rm -rf ~/.password-store/docker-credential-helpersFor macOS:
# Open Keychain Access and search for "docker"
# Delete any Docker-related entries
# Or use command line:
security delete-generic-password -s "Docker Credentials" 2>/dev/nullFor Windows:
1. Open Credential Manager (search in Start menu)
2. Click "Windows Credentials"
3. Find and remove entries starting with "docker"
Fresh start - remove all Docker config:
# Backup first
mv ~/.docker/config.json ~/.docker/config.json.backup
# Try logging in again (creates fresh config)
docker loginIf you want to use secure credential storage, install the appropriate helper for your OS.
On macOS:
# Install via Homebrew
brew install docker-credential-helper
# Verify installation
docker-credential-osxkeychain version
# Update config.json to use it
# Set "credsStore": "osxkeychain"On Linux (using secretservice - recommended for desktop):
# Download the latest release
VERSION=$(curl -s https://api.github.com/repos/docker/docker-credential-helpers/releases/latest | grep tag_name | cut -d '"' -f 4)
wget https://github.com/docker/docker-credential-helpers/releases/download/${VERSION}/docker-credential-secretservice-${VERSION}.linux-amd64
# Install it
chmod +x docker-credential-secretservice-*
sudo mv docker-credential-secretservice-* /usr/local/bin/docker-credential-secretservice
# Update config.json: "credsStore": "secretservice"On Linux (using pass - for headless/server):
# Install pass and docker-credential-pass
sudo apt install pass
# Download docker-credential-pass
VERSION=$(curl -s https://api.github.com/repos/docker/docker-credential-helpers/releases/latest | grep tag_name | cut -d '"' -f 4)
wget https://github.com/docker/docker-credential-helpers/releases/download/${VERSION}/docker-credential-pass-${VERSION}.linux-amd64
# Install it
chmod +x docker-credential-pass-*
sudo mv docker-credential-pass-* /usr/local/bin/docker-credential-pass
# Then initialize pass (see Step 3)Instead of a global credsStore, you can configure different credential helpers per registry using credHelpers:
{
"auths": {},
"credHelpers": {
"registry-1.docker.io": "osxkeychain",
"gcr.io": "gcr",
"123456789.dkr.ecr.us-east-1.amazonaws.com": "ecr-login",
"ghcr.io": "osxkeychain"
}
}This approach allows:
- Different helpers for different registries
- Fallback to plaintext for registries without a helper
- Mixing secure and less-secure storage as needed
For CI/CD environments, you might want no credential helpers at all:
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "base64encodedcredentials"
}
}
}VS Code's Dev Container extension adds a credential helper that can cause issues outside VS Code.
Symptom: Error includes "exit status 255" or works in VS Code terminal but not regular terminal.
Solution 1: Disable the Dev Container credential helper
In your .devcontainer/devcontainer.json:
{
"settings": {
"dev.containers.dockerCredentialHelper": false
}
}Solution 2: Remove the remote credential helper
Check your config.json for entries like "credsStore": "vscode" and remove them.
Solution 3: Set environment variable
When using Docker outside VS Code, unset the IPC variable:
unset REMOTE_CONTAINERS_IPC
docker login### Understanding Docker Credential Storage
Docker credentials can be stored in three ways:
1. Plaintext in config.json - Base64 encoded (easily decoded, use only for testing)
2. Credential helpers - Native OS secure storage (credsStore setting)
3. Per-registry helpers - Different helpers for different registries (credHelpers setting)
### Debugging Credential Helper Issues
Test your credential helper directly:
# Test if the helper works
echo "https://index.docker.io/v1/" | docker-credential-osxkeychain get
# List stored credentials
docker-credential-osxkeychain list
# Store a credential manually
echo '{"ServerURL":"https://index.docker.io/v1/","Username":"user","Secret":"password"}' | docker-credential-osxkeychain store### GPG Agent Issues with Pass
If you're using docker-credential-pass and getting GPG errors:
# Check if gpg-agent is running
gpg-agent --version
# Restart the agent
gpgconf --kill gpg-agent
gpg-agent --daemon
# Test GPG encryption
echo "test" | gpg --encrypt -r [email protected] | gpg --decrypt### Docker Desktop Credential Store Location
Docker Desktop stores credentials differently:
- macOS: Uses osxkeychain under the hood
- Windows: Uses wincred or a credential manager
- Both: May add "credsStore": "desktop" which requires Docker Desktop to be running
### CI/CD Best Practices
For automated environments:
# Use --password-stdin to avoid credential storage entirely
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
# Or use environment variables
export DOCKER_CONFIG=/tmp/docker-config
mkdir -p $DOCKER_CONFIG
docker login # Credentials stored in temp location, cleaned up after### WSL2 Specific Issues
In WSL2, you may encounter issues with credential helpers:
# Check if Docker Desktop integration is enabled
# Settings > Resources > WSL Integration
# If using standalone Docker in WSL2, remove any "desktop" references
# and use secretservice or pass instead### Multiple Docker Contexts
If you have multiple Docker contexts, each can have different credential configurations:
# List contexts
docker context ls
# Check which context is active
docker context show
# Switch context if needed
docker context use defaultimage operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub