Immediate Fix
The “unexpected status code 401” error during a Docker login usually indicates invalid credentials or an expired session. To resolve this immediately, try the following sequence of commands to clear your local state and re-authenticate.
| Action | Command |
|---|---|
| Log out of the registry |
|
| Force a fresh login |
|
| Login to specific registry |
|
If you are using Docker Desktop, ensure you are not logged in with an expired Personal Access Token (PAT). Generate a new token from your Docker Hub account settings and use that instead of your standard password.
Technical Explanation
In the context of HTTP status codes, 401 Unauthorized means the server received the request, but the client must authenticate itself to get the requested response. For Docker, this happens at the Registry API level.
Common Causes
1. Expired Tokens: If you use Personal Access Tokens (PATs) for security, they may have reached their expiration date. Docker will continue trying to use the cached, expired token found in your config.json.
2. Two-Factor Authentication (2FA): If you have enabled 2FA on Docker Hub or a private registry like GitHub Packages (GHCR), you cannot use your account password. You must use a generated token.
3. Credential Helper Issues: Docker uses credential helpers (like osxkeychain or wincred) to store secrets. If the helper is out of sync or the stored entry is corrupted, it will send the wrong data, triggering the 401 error.

Alternative Methods
If the standard login command continues to fail, you may need to manually clean your configuration or use environment variables to bypass the interactive prompt.
Manual Config Cleanup
Locate your ~/.docker/config.json file. Sometimes, old entries for specific registries remain cached. You can manually delete the “auths” block associated with the failing registry URL and then try logging in again.
# Example of logging in via STDIN (useful for CI/CD)
echo "YOUR_ACCESS_TOKEN" | docker login --username YOUR_USERNAME --password-stdin
Check Registry Permissions
If you are pushing to a private organization or a specific repository, ensure your user account has “Write” or “Admin” permissions. Even with a valid login, some registries return a 401 if the user lacks access to the specific namespace you are targeting.
Finally, verify if you are behind a corporate proxy or firewall. Some deep-packet inspection tools can intercept the authentication headers, causing the registry to see the request as unauthorized.