How to know if docker is already logged in to a docker registry server
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
To check whether Docker is logged in to a registry, inspect the ~/.docker/config.json file. If the registry hostname appears under the auths key (or a credsStore / credHelpers entry handles it), Docker has stored credentials for that registry. There is no dedicated docker is-logged-in command, so reading this config file is the standard approach.
The rest of this article covers how Docker stores credentials across different platforms, how to write reliable login checks for CI/CD pipelines, and how to troubleshoot authentication when things go wrong.
How Docker Stores Credentials
When you run docker login, Docker persists credentials so that subsequent docker push and docker pull commands do not require re-authentication. The storage mechanism depends on your OS and Docker configuration.
Direct Storage in config.json
On systems without a credential helper, Docker stores a base64-encoded username:password string directly in ~/.docker/config.json:
Each key under auths is a registry URL. If your target registry appears here with a non-empty auth value, you are logged in.
You can decode the value to verify the username:
Credential Helpers
Modern Docker installations delegate credential storage to the operating system's native keychain. In this case, config.json contains a credsStore key instead of inline credentials:
| OS | Credential Helper | Storage Backend |
| macOS | osxkeychain | Keychain Access |
| Windows | wincred | Windows Credential Manager |
| Linux (GNOME) | secretservice | GNOME Keyring |
| Linux (headless) | pass | GPG-encrypted pass store |
| Docker Desktop | desktop | Docker Desktop internal store |
When a credential helper is configured, the auth field under auths is empty because the actual secret lives in the OS keychain. The presence of the registry key still indicates that Docker has stored credentials for it.
Per-Registry Credential Helpers
You can also configure different helpers for different registries using credHelpers:
Cloud provider registries (ECR, GCR, ACR) often use their own credential helper binaries that generate short-lived tokens on the fly, so the concept of "logged in" means the helper is configured, not that a static credential is cached.
Checking Login Status Programmatically
Quick Shell Check
To test whether credentials exist for a specific registry in a script:
Using jq for Reliable Parsing
Parsing JSON with grep is fragile. Use jq for accurate checks:
The -e flag makes jq return a non-zero exit code if the result is null or false, which makes it usable in conditionals.
Verifying Active Credentials With a Test Pull
Having credentials in config.json does not guarantee they are still valid. Tokens expire, passwords get rotated, and accounts get deactivated. To verify that credentials actually work:
A lighter alternative is to query the registry API directly:
A 200 response confirms valid authentication.
Custom Config Path
The default config location is ~/.docker/config.json, but Docker respects the DOCKER_CONFIG environment variable. In CI/CD environments, you may see:
Always use ${DOCKER_CONFIG:-$HOME/.docker}/config.json in scripts to handle custom paths:
CI/CD Pipeline Patterns
GitHub Actions
Login Guard Script
A reusable pattern for any CI system:
Logging Out
To remove credentials for a specific registry:
To remove all stored credentials:
After logging out, the registry entry is removed from (or emptied in) config.json. You can verify by inspecting the file again.
Common Pitfalls
Assuming the auth field in config.json always contains a value is incorrect when a credential helper is configured. The field may be empty or the key may exist with an empty object, while the real credentials live in the OS keychain.
Checking for docker.io instead of https://index.docker.io/v1/ trips up many scripts. Docker Hub uses the full URL as its registry key, not the short hostname. Always verify the exact key format in your config.json.
Using docker login interactively in CI/CD pipelines creates issues because it prompts for input. Always use --password-stdin to pipe the password:
Forgetting that DOCKER_CONFIG can override the default config path means your script checks the wrong file. Always incorporate the environment variable in automated checks.
Storing plaintext credentials in config.json without a credential helper is a security risk on shared machines. Configure a credential helper or use short-lived tokens.
Having expired or rotated credentials in config.json produces confusing "authentication required" errors on push/pull even though the file shows you are "logged in." Validate credentials by actually authenticating, not just checking file contents.
Summary
- Inspect
~/.docker/config.jsonand look for your registry under theauthskey to determine login status. - Account for credential helpers (
credsStore,credHelpers) that store secrets in the OS keychain instead of the config file. - Use
jqfor reliable JSON parsing in scripts rather thangrep. - Respect the
DOCKER_CONFIGenvironment variable for non-default config paths. - Having credentials stored does not guarantee they are valid. Test with an actual pull or API call when freshness matters.
- Use
docker logoutto cleanly remove stored credentials.

