The 'unauthorized: incorrect username or password' error occurs when Docker cannot authenticate with the container registry. This typically happens because you're using your email instead of username, your password contains special characters, or you need to use a Personal Access Token instead of your password.
This error indicates that the Docker daemon failed to authenticate with the container registry (typically Docker Hub) when attempting to log in or pull/push images. The registry rejected the provided credentials. The authentication flow works as follows: Docker sends your credentials to the registry's authentication service, which validates them and returns a token. If the credentials are invalid, expired, or malformed, the registry returns this "unauthorized" error. Common scenarios that trigger this error: 1. **Using email instead of username** - Docker Hub requires your username (not your email address) for CLI authentication 2. **Password with special characters** - Some special characters in passwords can cause issues with shell escaping 3. **Two-factor authentication enabled** - When 2FA is enabled, you must use a Personal Access Token (PAT) instead of your password 4. **Cached credentials are stale** - Old credentials stored in the Docker credential store may be outdated 5. **System time is incorrect** - Authentication tokens are time-sensitive and will fail if your system clock is significantly off
Docker Hub requires your username for CLI authentication, not your email address. Your username is displayed in the top-right corner when logged into Docker Hub.
# Wrong - using email
docker login -u [email protected]
# Correct - using username (lowercase)
docker login -u myusernameImportant: Docker Hub usernames are case-insensitive on the website but the CLI requires lowercase. If your username shows as "MyUsername" on the site, use "myusername" in the CLI.
To find your username:
1. Go to [hub.docker.com](https://hub.docker.com)
2. Sign in with your email
3. Your username appears in the top-right corner
If you have two-factor authentication (2FA) enabled, or if password login keeps failing, use a Personal Access Token (PAT) instead:
Create a Personal Access Token:
1. Log in to [hub.docker.com](https://hub.docker.com)
2. Click your username > Account Settings
3. Select Security from the left menu
4. Click New Access Token
5. Enter a description (e.g., "CLI access")
6. Select the appropriate permissions (Read/Write for push, Read for pull only)
7. Click Generate and copy the token
Use the token to log in:
# Using the token as your password
docker login -u myusername
# When prompted for password, paste your access token
# Or non-interactively (for CI/CD)
echo "YOUR_ACCESS_TOKEN" | docker login -u myusername --password-stdinNote: Access tokens are required when 2FA is enabled. Your regular password will not work.
Corrupted or stale credentials can cause authentication failures. Clear them completely:
# Log out from Docker Hub
docker logout
# Check where credentials are stored
cat ~/.docker/config.jsonIf you see a credsStore field, credentials are managed by a credential helper. Clear those as well:
On Linux (using pass or secretservice):
# Remove Docker credentials from the secret store
# For GNOME Keyring/secretservice
secret-tool clear server registry-1.docker.io
# Or rename the config to start fresh
mv ~/.docker/config.json ~/.docker/config.json.backupOn macOS:
# Remove from Keychain
security delete-generic-password -s "Docker Credentials"On Windows:
- Open Credential Manager
- Find and remove Docker-related entries
Then log in again:
docker login -u myusernameAuthentication tokens are time-sensitive. If your system clock is significantly wrong, authentication will fail.
# Check current system time
date
# Compare with actual time
# If off by more than a few minutes, sync it:
# On Linux (systemd)
sudo timedatectl set-ntp true
sudo systemctl restart systemd-timesyncd
# On macOS
sudo sntp -sS time.apple.com
# On Windows (PowerShell)
w32tm /resyncDocker Desktop on Windows/Mac should automatically sync time with the host, but VM clock drift can occur after sleep/hibernate.
Sometimes specifying the registry URL explicitly can help:
# Log in specifying Docker Hub explicitly
docker login docker.io
# Or with the full registry URL
docker login registry-1.docker.io
# For other registries, use their specific URLs
docker login ghcr.io # GitHub Container Registry
docker login gcr.io # Google Container Registry
docker login your-registry.azurecr.io # Azure Container RegistryThis ensures Docker is authenticating against the correct registry.
If your password contains special characters, they may be misinterpreted by the shell. Use the --password-stdin flag to avoid shell escaping issues:
# Safe way to pass passwords with special characters
echo 'my$pecial!Pa$$word' | docker login -u myusername --password-stdin
# Or use a file (make sure to delete it afterward)
cat password.txt | docker login -u myusername --password-stdin
rm password.txtAlternatively, change your Docker Hub password to one without problematic characters like:
- $ (variable expansion)
- ! (history expansion)
- ' or " (quote characters)
- \ (escape character)
If you run Docker with sudo, credentials are stored in root's home directory. Be consistent:
# If you use sudo for Docker commands
sudo docker login -u myusername
sudo docker pull myimage
# Credentials stored in /root/.docker/config.json
# If you don't use sudo (user in docker group)
docker login -u myusername
docker pull myimage
# Credentials stored in ~/.docker/config.jsonTo avoid needing sudo:
# Add your user to the docker group
sudo usermod -aG docker $USER
# Log out and back in, or run:
newgrp docker
# Now docker commands work without sudo
docker login -u myusername### Device Code Authentication Flow
Docker Desktop and recent Docker CLI versions support a more secure device code flow:
# Modern authentication (opens browser)
docker login
# This opens a browser for authentication, avoiding password entry in terminal### Debugging Authentication Issues
Check your Docker configuration and credentials:
# View Docker config (don't share this - may contain encoded credentials)
cat ~/.docker/config.json
# Test registry connectivity
curl -v https://registry-1.docker.io/v2/
# Check if credentials are working by listing your repositories
docker search myusername/### CI/CD Pipeline Authentication
For automated environments, always use access tokens with minimal required permissions:
# GitHub Actions example
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}# GitLab CI example
docker-login:
script:
- echo "$DOCKER_TOKEN" | docker login -u "$DOCKER_USER" --password-stdin### Multiple Registry Authentication
Docker stores credentials per-registry. You can be logged into multiple registries simultaneously:
docker login # Docker Hub
docker login ghcr.io # GitHub
docker login gcr.io # Google
docker login myregistry.azurecr.io # AzureCheck all stored authentications:
cat ~/.docker/config.json | jq '.auths | keys'### Docker Desktop vs CLI
If Docker Desktop is installed, it may manage credentials differently than the CLI. Try signing out of Docker Desktop UI first, then use CLI login:
1. Docker Desktop > Sign out
2. docker logout
3. docker login -u username
### Token Expiration
Personal Access Tokens can be set to expire. Check your token settings at hub.docker.com if authentication suddenly stops working. Consider creating tokens with no expiration for CI/CD, but rotate them periodically for security.
dockerfile parse error line 5: unknown instruction: RRUN
How to fix 'unknown instruction' Dockerfile parse error in Docker
Error response from daemon: manifest for nginx:nonexistent not found: manifest unknown: manifest unknown
How to fix 'manifest for image:tag not found' in Docker
Error response from daemon: invalid reference format: repository name must be lowercase
How to fix 'repository name must be lowercase' in Docker
Error response from daemon: No such image
How to fix 'No such image' in Docker
Error response from daemon: Container is not running
How to fix 'Container is not running' when using docker exec