How to Fix Docker "Pull Access Denied, Repository Does Not Exist"
The Docker "pull access denied, repository does not exist" error has four common causes, and only one of them involves authentication. In order of likelihood: a typo in the image name, a missing Docker Hub namespace, authentication against the wrong registry, or an account that genuinely lacks pull permissions. Work through them in that order because most developers waste time on login issues when the real problem is a misspelled image tag.
Cause 1: Typo or Wrong Image Name
Docker interprets any string you pass to docker pull as a real repository path. It offers no "did you mean" suggestion. A single wrong character produces the same generic error as a permissions failure. Always verify the exact image name on Docker Hub or your private registry's UI before debugging further.
# Wrong — common typos that produce this exact error.
docker pull ubunutu
docker pull nginx:latets
docker pull python:3.11-slm
# Right — verify spelling and tag names.
docker pull ubuntu
docker pull nginx:latest
docker pull python:3.11-slim
Cause 2: Missing Namespace or Registry Prefix
Docker Hub has two kinds of images: official library images (like nginx) and user/org images (like mycompany/api-server). If you omit the namespace on a non-official image, Docker looks for a library image that doesn't exist. If your image lives on a private registry like AWS ECR, GitHub Container Registry, or Google Artifact Registry, you must include the full registry hostname.
# Wrong — missing the namespace for a Docker Hub org image.
docker pull api-server
# Right — include the Docker Hub namespace.
docker pull mycompany/api-server:1.2.0
# Right — include the full hostname for private registries.
docker pull ghcr.io/myorg/api-server:1.2.0
docker pull 123456789.dkr.ecr.us-east-1.amazonaws.com/api-server:1.2.0
docker pull us-docker.pkg.dev/my-project/my-repo/api-server:1.2.0
Cause 3: Not Logged in or Logged in to the Wrong Registry
Running docker login with no arguments authenticates you against Docker Hub. If your image lives on a different registry, you must pass the registry hostname explicitly. A common gotcha is that docker login succeeds but you're authenticated to the wrong endpoint, so pulls still fail with the same error message.
# Log in to Docker Hub.
docker login
# Log in to GitHub Container Registry.
docker login ghcr.io -u YOUR_GITHUB_USERNAME
# Log in to AWS ECR (requires AWS CLI configured).
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin \
123456789.dkr.ecr.us-east-1.amazonaws.com
# Log in to Google Artifact Registry.
gcloud auth configure-docker us-docker.pkg.dev
Verify Your Stored Docker Credentials
Docker stores credentials in ~/.docker/config.json. Inspecting this file tells you exactly which registries you're authenticated with. If you see an empty auths object or the wrong hostname, that's your problem.
# Check which registries have stored credentials.
cat ~/.docker/config.json | python3 -m json.tool
# Expected output for Docker Hub and GHCR.
# {
# "auths": {
# "https://index.docker.io/v1/": {},
# "ghcr.io": {}
# },
# "credsStore": "desktop"
# }
Cause 4: Insufficient Permissions on a Private Repository
If the image lives in a private repository, being logged in isn't enough. Your account or token needs explicit read access. On Docker Hub, the repo owner must add you as a collaborator or team member. On GitHub, your personal access token needs the read:packages scope. On AWS ECR, your IAM policy needs ecr:GetDownloadUrlForLayer, ecr:BatchGetImage, and ecr:GetAuthorizationToken. The error message is identical regardless of which permission is missing.
# Generate a GitHub PAT with the correct scope and log in.
export CR_PAT="ghp_your_token_here"
echo $CR_PAT | docker login ghcr.io -u YOUR_USERNAME --password-stdin
# Verify the token has the right scope (GitHub API check).
curl -sS -H "Authorization: Bearer $CR_PAT" \
https://api.github.com/user | jq '.login'
Cause 5 (Dockerfiles): Typo in the FROM Instruction
This same error appears during docker build when your FROM line references a nonexistent base image. This is common when you use multi-stage builds or organization-internal base images where the tag has been deleted or the registry prefix is missing.
# Wrong — typo in the base image name inside a Dockerfile.
# FROM nod:18-alpine
# Right — correct the spelling.
# FROM node:18-alpine
# Verify an image exists before building.
docker manifest inspect node:18-alpine > /dev/null 2>&1 && \
echo "Image exists" || echo "Image NOT found"
Gotchas and Edge Cases
Docker Desktop credential store conflicts: On macOS and Windows, Docker Desktop uses a native credential store (osxkeychain or wincred). If the credential helper is misconfigured, docker login reports success but never stores the credentials. If you're stuck, temporarily remove the credsStore key from ~/.docker/config.json to fall back to plain file-based storage and test again.
Rate limiting on Docker Hub: Anonymous pulls from Docker Hub are rate-limited to 100 pulls per six hours per IP. When you hit the limit, you sometimes get this error instead of a clear rate-limit message. Logging in with a free Docker Hub account raises the limit to 200 pulls. Use docker login even for public images in CI/CD pipelines.
Platform mismatch is a different error: If you're on an ARM machine pulling an amd64-only image, Docker gives a different error about platform mismatch. Don't confuse the two. The "pull access denied" error is never about architecture.