Skip to content
DevOps AI ToolKit
Newsletter
All guides
Docker with AI By James Joyner IV · · 9 min read

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/api vs myorg/apis resolves to a path you have no access to (or that does not exist), which returns denied.
  • 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.json entry pointing at the wrong registry produces a denied even though you “logged in” once.
  • Wrong registry namespace. Pulling api:latest (Docker Hub library namespace) when the image lives at myorg/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:packages scope 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 login step in CI before any pull, and fail fast with a clear message if it errors.
  • Store credentials in a credsStore/secret manager instead of plaintext config.json, and rotate before expiry.
  • Mirror critical public base images into a private registry to decouple from third-party auth and rate limits.
Free download · 368-page PDF

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.