Docker Error Guide: 'no basic auth credentials' — Fix Registry Push/Pull Auth
Fix 'no basic auth credentials' in Docker: log in to the right registry, match the image name to your login host, refresh expired tokens, and repair the credential store.
- #docker
- #troubleshooting
- #errors
- #registry
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
Docker raises this error when it tries to push (or pull) an image to a registry but has no usable credentials for that registry’s hostname. It appears at the end of a docker push, or during a docker pull of a private repository:
denied: requested access to the resource is denied
errors:
denied: requested access to the resource is denied
unauthorized: authentication required
no basic auth credentials
The final line — no basic auth credentials — is the specific one: Docker looked in its config for credentials matching the registry host of the image reference and found none, so it sent the request without any auth.
Symptoms
docker push myrepo/app:1.0fails withno basic auth credentialseven thoughdocker loginappeared to succeed earlier.- Pushing to a private or third-party registry (GHCR, ECR, GCR, Harbor, a self-hosted registry) fails, while Docker Hub works.
- The error appears only in CI, not on a developer laptop where you logged in interactively.
docker loginreturnsLogin Succeededbut a subsequent push still saysno basic auth credentials.- Pulls of public images work; only private repositories fail.
Common Root Causes
- Never logged in to this registry — you ran
docker loginfor Docker Hub but are pushing toghcr.ioor a private host you never authenticated against. - Image name host mismatch — the image is tagged
myrepo/app(implicitly Docker Hub) but you meant a private registry, or vice versa; Docker matches credentials by the host portion of the reference. - Expired or short-lived token — cloud registries (ECR, GCR, ACR) issue tokens that expire; an old login is stale.
- Credentials not persisted in CI — the login happened in a different shell/step, or the runner’s
~/.docker/config.jsonis not shared across steps. - Credential helper misconfigured —
credsStore/credHelpersinconfig.jsonpoints to a helper binary that is missing or failing, so no credentials are returned. - Wrong user home / config path — the push runs as a different user (e.g.
sudoor a service account) whose~/.docker/config.jsonhas no login. - Registry needs a namespace you cannot write to — you are authenticated but the token lacks push scope for that repository (this surfaces as
deniedalongside the auth line).
Diagnostic Workflow
Confirm exactly what host the image reference points at, then check whether config holds credentials for that host.
# The registry host is the part before the first slash IF it contains a dot or port.
# 'myrepo/app' -> docker.io (Docker Hub)
# 'ghcr.io/org/app' -> ghcr.io
docker image inspect myrepo/app:1.0 --format '{{.RepoTags}}'
Inspect which registries the current user is actually logged in to:
cat ~/.docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {}
},
"credsStore": "desktop"
}
Here auths only lists Docker Hub — a push to ghcr.io will fail with no basic auth credentials. Note whether credsStore or credHelpers is set, because then the actual secret lives in an external helper, not in this file.
Confirm which user and home directory the failing command runs as (critical in CI or under sudo):
whoami
echo "$HOME"
sudo docker push myrepo/app:1.0 # sudo may read /root/.docker, not your login
Test the credential helper directly if one is configured:
# replace 'desktop' with your credsStore value
echo 'ghcr.io' | docker-credential-desktop get
If the helper errors or returns nothing for the host, that is the failure.
Example Root Cause Analysis
A CI pipeline built and pushed an image to GitHub Container Registry. The build step ran docker login ghcr.io successfully, but the push in a later step failed:
The push refers to repository [ghcr.io/acme/api]
denied: no basic auth credentials
Diagnosis: the two steps ran in separate containers, and docker login wrote credentials to ~/.docker/config.json in the login step’s container, which was discarded before the push step started. Inspecting the push step showed an empty auths block. The image reference and scopes were correct — the credentials simply were not present at push time.
Fix: perform the login and push in the same job/step (or persist ~/.docker/config.json between steps), passing the token via stdin so it is never in the process list:
echo "$GHCR_TOKEN" | docker login ghcr.io -u "$GHCR_USER" --password-stdin
docker push ghcr.io/acme/api:1.0
The push then succeeded because the credentials for ghcr.io were present in the same environment as the push.
Prevention Best Practices
- Tag images with the full registry host (
ghcr.io/org/app,myregistry.example.com/app) so it is unambiguous which credentials Docker needs. - Log in and push in the same CI job/environment, or explicitly persist
~/.docker/config.jsonacross steps. - Always use
--password-stdininstead of-pon the command line to keep tokens out of shell history and process listings. - For cloud registries, refresh short-lived tokens right before push (e.g.
aws ecr get-login-password | docker login ...) rather than relying on an old login. - Run
docker pushas the same user that randocker login; avoid mixingsudoand per-user credentials. - Verify the token’s scope includes write/push for the target repository, not just read.
Quick Command Reference
# Log in to a specific registry via stdin (no secret in shell history)
echo "$TOKEN" | docker login ghcr.io -u "$USER" --password-stdin
# Docker Hub login
docker login # defaults to docker.io
# See which registries you have credentials for
cat ~/.docker/config.json
# Refresh an ECR token and log in
aws ecr get-login-password --region us-east-1 \
| docker login --username AWS --password-stdin <acct>.dkr.ecr.us-east-1.amazonaws.com
# Test a configured credential helper for a host
echo 'ghcr.io' | docker-credential-<store> get
# Log out to clear stale credentials, then log in again
docker logout ghcr.io
Conclusion
no basic auth credentials means Docker had no credentials matching the registry host in your image reference at the moment of the request. Trace it in two moves: confirm the exact host the image is tagged for, then confirm that the user and environment running the command hold a valid, unexpired login for that host. Matching the login host to the image tag, keeping login and push in the same environment, and refreshing short-lived tokens resolves the vast majority of cases.
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.