Docker Error Guide: 'pull access denied for <image>, repository does not exist or may require docker login' Registry Auth Failures
Fix Docker 'pull access denied... requested access to the resource is denied': run docker login, correct the namespace, check ~/.docker/config.json, and verify the image exists.
- #docker
- #troubleshooting
- #errors
- #registry
Exact Error Message
When Docker cannot authorize a pull, the daemon returns:
Error response from daemon: pull access denied for myorg/api, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
The message has two halves. pull access denied for <image>, repository does not exist or may require 'docker login' is the daemon’s generic interpretation; denied: requested access to the resource is denied is the registry’s verbatim response. The registry deliberately conflates “this repo is private and you are not authorized” with “this repo does not exist” so it never confirms the existence of a private image to an anonymous caller.
You will encounter this on docker pull, on docker run (which pulls implicitly), during a docker compose up, in a FROM line at build time, and from CI runners that pull base or app images. The registry host varies — Docker Hub, GHCR, ECR, GCR, Quay, or a self-hosted registry — but the denied: requested access to the resource is denied tail is identical across all of them, because it is the OCI distribution spec’s standard authorization error.
What It Means
The daemon sent a manifest request to the registry on your behalf and the registry replied with a 403-class denied error. From the registry’s point of view the request was either unauthenticated, authenticated as a principal without read access to that repository, or pointed at a path that does not exist. Because the registry returns the same denied for “private and unauthorized” and “no such repo,” Docker cannot tell you which, so it lists both possibilities. The pull never starts: no layers download and no image lands in your local store.
Common Causes
- Typo in the image or repository name.
myorg/apivsmyorg/apisresolves to a path you have no access to (or that does not exist), which returnsdenied. - Private repository with no
docker login. An anonymous pull of a private image is rejected; the registry will not even confirm the repo exists. - Expired or incorrect credentials. A stale token, rotated password, or a
config.jsonentry pointing at the wrong registry produces adeniedeven though you “logged in” once. - Wrong registry namespace. Pulling
api:latest(Docker Hub library namespace) when the image lives atmyorg/api, or omitting the registry host for GHCR/ECR/GCR. - The image genuinely does not exist. Never pushed, deleted, or pushed to a different account.
- Org SSO / token scope. Organization SSO enforcement or a personal access token without
read:packagesscope authenticates you but denies the repo. - Rate limit masquerading as auth. Docker Hub may surface throttling as an access problem; an authenticated pull behaves differently from an anonymous one.
How to Reproduce the Error
Pull a private repository without logging in, or pull a name that does not exist:
docker logout docker.io
docker pull myorg/api:latest
Error response from daemon: pull access denied for myorg/api, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
Diagnostic Commands
Confirm whether you are authenticated and to which registry:
cat ~/.docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {}
},
"credsStore": "desktop"
}
An empty auths entry (or a credsStore you cannot reach) means the daemon is pulling anonymously. Try an explicit login and re-pull:
docker login docker.io
docker pull myorg/api:latest
Probe the manifest directly to separate “auth” from “not found.” docker manifest inspect uses your stored credentials:
docker manifest inspect myorg/api:latest
If this still returns denied after a successful docker login, the credential is valid but lacks read access to that specific repo (scope/SSO), or the path is wrong. Verify the exact reference you are sending:
docker pull --debug ghcr.io/myorg/api:latest 2>&1 | grep -i 'GET\|denied\|401\|403'
For registries that issue short-lived tokens (ECR, GCR), confirm the helper actually wrote a credential and the daemon can see the registry host:
docker info | grep -i registry
journalctl -u docker --since "5 min ago" | grep -i 'denied\|auth'
Step-by-Step Resolution
Cause: typo or wrong namespace. Print the exact image string from whatever launched the pull (compose file, docker run, CI), and compare it to the registry UI. For Docker Hub, official images live under library/ (docker pull nginx), user images under user/repo. For GHCR/ECR/GCR you must include the host: ghcr.io/myorg/api, 123456789.dkr.ecr.us-east-1.amazonaws.com/api.
Cause: private repo, not logged in. Authenticate to the correct registry, then re-pull:
docker login ghcr.io -u <user> --password-stdin <<< "$GHCR_TOKEN"
docker pull ghcr.io/myorg/api:latest
Cause: expired or wrong credentials. Log out, clear the stale entry, and log back in with a current token:
docker logout ghcr.io
docker login ghcr.io
If you use a credsStore/credHelpers, confirm the helper binary is on PATH and returns a token; a broken helper looks identical to bad credentials.
Cause: token scope / org SSO. Re-issue the personal access token with read:packages (GHCR) or the equivalent registry read scope, and authorize it for SSO in the org settings. ECR needs ecr:GetDownloadUrlForLayer and ecr:BatchGetImage on the IAM principal.
Cause: image does not exist. Confirm in the registry UI or via docker manifest inspect after authenticating. If it was never pushed, push it; if it was deleted, restore or rebuild it. Keep in mind the registry returns denied rather than a clear “not found” for private namespaces, so an authenticated docker manifest inspect that now returns manifest unknown is strong evidence the repo is reachable but the image is genuinely absent.
Cause: cloud registry token expiry (ECR/GCR/ACR). These registries issue short-lived tokens through a credential helper. If the helper has not refreshed, the daemon presents an expired token and the registry returns denied. Re-run the helper’s login command and confirm the helper is wired into config.json:
aws ecr get-login-password --region us-east-1 \
| docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com
grep -A2 credHelpers ~/.docker/config.json
Cause: rate limit. If docker manifest inspect works while docker pull fails intermittently, authenticate the pull (logged-in pulls have higher limits) or mirror the image into your own registry. Docker Hub’s toomanyrequests is the cleaner signal, but throttling can occasionally surface through the daemon as an access problem; compare an authenticated pull against an anonymous one to tell them apart.
A quick decision table once you have run the diagnostics:
docker manifest inspect ... Pull result Likely cause
--------------------------- ------------ ------------
denied (anonymous) denied private repo, not logged in
denied (after docker login) denied token scope / SSO / wrong repo
OK denied stale credsStore or wrong namespace in the run command
not found denied typo or image truly absent
OK intermittently denied/429 rate limit
How to Prevent the Issue
- Pin the full reference including registry host and namespace in compose files and manifests, so the path is unambiguous.
- Use a CI service account with a read-scoped, automation-rotated token rather than a developer’s personal credential.
- Run a
docker loginstep in CI before any pull, and fail fast with a clear message if it errors. - Store credentials in a
credsStore/secret manager instead of plaintextconfig.json, and rotate before expiry. - Mirror critical public base images into a private registry to decouple from third-party auth and rate limits.
Related Docker Errors
- Docker Error Guide: ‘manifest unknown’ — the repo is accessible but the requested tag or digest does not exist.
- Docker Error Guide: ‘no matching manifest for linux/amd64’ — the image exists and you can read it, but not for your platform.
- See more Docker troubleshooting guides.
Download the Free 500-Prompt DevOps AI Toolkit
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.