Introduction

Docker returns "unauthorized: authentication required" when it can successfully reach the container registry, but the registry rejects the provided credentials or the credentials don't grant access to the specific image being requested. This error is distinct from network connectivity issuesβ€”the registry is reachable, but authentication or authorization has failed.

Container registries like Docker Hub, Amazon ECR, Google Container Registry (GCR), Azure Container Registry (ACR), and private registries all require authentication for private images. The authentication chain involves the registry hostname, valid credentials with appropriate scope, and correct configuration in Docker or Kubernetes. Any break in this chain results in unauthorized errors.

Understanding the difference between authentication and authorization is helpful here. Authentication means proving your identity (valid credentials), while authorization means having permission to access the specific resource (the image). You can be authenticated but unauthorized if your credentials don't include access to the particular repository or namespace.

Symptoms

When Docker image pull authentication fails, you will observe these symptoms:

  • docker pull command fails with unauthorized: authentication required error
  • Authentication succeeds for one image or repository but fails for another
  • Kubernetes Pods fall into ImagePullBackOff status with registry authentication errors
  • A registry migration, token rotation, or permission change broke previously working image pulls
  • CI/CD pipelines fail at the image pull stage
  • Local development works but production deployments fail (or vice versa)

Common error messages:

bash
Error response from daemon: pull access denied for my-private-image, repository does not exist or may require 'docker login'
unauthorized: authentication required
Error: image my-private-image:latest not found

Kubernetes ImagePullBackOff errors:

bash
Failed to pull image "registry.example.com/my-org/my-image:latest":
rpc error: code = Unknown desc = failed to pull and unpack image "registry.example.com/my-org/my-image:latest":
failed to resolve reference "registry.example.com/my-org/my-image:latest":
failed to authorize: failed to fetch anonymous token: unexpected status: 401 Unauthorized

Common Causes

Several factors cause Docker image pull unauthorized errors:

  1. 1.Wrong registry hostname: Docker credentials are tied to specific registry hostnames. Logging into docker.io doesn't authenticate you for registry.hub.docker.com or custom registries. Even slight variations in hostname (with or without https://, with or without port numbers) can cause authentication failures.
  2. 2.Expired or invalid credentials: Docker login tokens expire, passwords are rotated, or API tokens are revoked. The credential store may contain stale authentication data.
  3. 3.Insufficient token scope: A token may authenticate successfully but lack permissions for the specific repository, namespace, or operation (pull vs push).
  4. 4.Misconfigured credential helper: Credential helpers for cloud registries (ECR, GCR, ACR) may be missing, misconfigured, or returning expired credentials.
  5. 5.Incorrect Kubernetes image pull secrets: The secret may reference the wrong registry server, contain outdated credentials, or not be properly associated with the ServiceAccount or Pod.
  6. 6.Repository doesn't exist: Sometimes "unauthorized" actually means the repository doesn't exist and the registry is protecting that information by not revealing existence.
  7. 7.Rate limiting: Docker Hub implements rate limits that can cause 401 errors when exceeded, even with valid credentials.

Step-by-Step Fix

Follow these steps to diagnose and resolve Docker image pull unauthorized errors:

Step 1: Verify the exact registry hostname

Identify the exact registry hostname from the image name:

```bash # Parse the image name # Format: [registry/]repo[:tag] # Examples: # nginx:latest -> registry: docker.io (default) # myimage:latest -> registry: docker.io (default) # registry.example.com/myimage -> registry: registry.example.com # 123456789.dkr.ecr.us-east-1.amazonaws.com/myimage -> registry: 123456789.dkr.ecr.us-east-1.amazonaws.com

# Check what registries you're logged into cat ~/.docker/config.json | jq '.auths | keys'

# Example output: # [ # "https://index.docker.io/v1/", # "registry.example.com" # ] ```

Step 2: Log in to the correct registry

Authenticate to the exact registry hostname used in the image:

```bash # For Docker Hub docker login

# For private registry docker login registry.example.com

# For AWS ECR aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com

# For Google Container Registry (GCR) gcloud auth configure-docker gcr.io

# For Google Artifact Registry (GAR) gcloud auth configure-docker us-docker.pkg.dev

# For Azure Container Registry (ACR) az acr login --name myregistry ```

Step 3: Inspect stored Docker credentials

Verify credentials are stored correctly:

```bash # View Docker config cat ~/.docker/config.json

# Check if credentials exist for your registry docker-credential-desktop list # For Docker Desktop on Mac/Windows # or docker-credential-osxkeychain list # For Mac keychain

# For Linux with pass credential store pass show docker-credential-helpers/docker-credential-pass

# Test credential by accessing the registry API curl -v https://registry.example.com/v2/ ```

Step 4: Verify repository permissions

Check that your account or token has access to the specific repository:

```bash # For Docker Hub, verify repository access in UI # Or use Docker Hub API curl -H "Authorization: Bearer $TOKEN" https://hub.docker.com/v2/repositories/myorg/

# For AWS ECR, check repository policies aws ecr describe-repositories --repository-names my-repo aws ecr get-repository-policy --repository-name my-repo

# For ACR, check permissions az acr repository show --name myregistry --image myimage:latest ```

Step 5: Fix Kubernetes image pull secrets

For Kubernetes workloads, verify and recreate image pull secrets:

```bash # Check existing secrets kubectl get secrets -n my-namespace kubectl describe secret my-registry-secret -n my-namespace

# Decode and verify the secret contents kubectl get secret my-registry-secret -n my-namespace -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d | jq

# Create a new image pull secret kubectl create secret docker-registry my-registry-secret \ --docker-server=registry.example.com \ --docker-username=myuser \ --docker-password=mypassword \ --docker-email=myemail@example.com \ -n my-namespace

# For AWS ECR kubectl create secret docker-registry ecr-secret \ --docker-server=123456789.dkr.ecr.us-east-1.amazonaws.com \ --docker-username=AWS \ --docker-password=$(aws ecr get-login-password --region us-east-1) \ -n my-namespace

# Update the Pod/Deployment to use the secret kubectl patch serviceaccount default -n my-namespace -p '{"imagePullSecrets": [{"name": "my-registry-secret"}]}' ```

Step 6: Configure credential helpers for cloud registries

Set up credential helpers for automatic authentication:

```bash # For AWS ECR - install and configure # ~/.docker/config.json: { "credHelpers": { "public.ecr.aws": "ecr-login", "<account-id>.dkr.ecr.<region>.amazonaws.com": "ecr-login" } }

# For GCR/GAR gcloud auth configure-docker

# For ACR # Use az acr login or configure credential helper ```

Step 7: Test authentication with a manual pull

Verify authentication works:

```bash # Try pulling a specific image docker pull registry.example.com/myorg/myimage:latest

# If using Kubernetes, create a test pod kubectl run test-pull --image=registry.example.com/myorg/myimage:latest --restart=Never -n my-namespace

# Check the pod status kubectl get pod test-pull -n my-namespace kubectl describe pod test-pull -n my-namespace ```

Step 8: Check Docker Hub rate limits

If using Docker Hub, verify you haven't hit rate limits:

```bash # Check rate limit status curl -s -H "Authorization: Bearer $TOKEN" https://registry.hub.docker.com/v2/users/docker/ | jq

# Get anonymous rate limit curl -sI https://registry.hub.docker.com/v2/library/nginx/manifests/latest | grep -i ratelimit

# Rate limit headers: # ratelimit-limit: 100;w=21600 (100 requests per 6 hours for anonymous) # ratelimit-remaining: 95 ```

Verification

After fixing authentication, verify image pulls work:

```bash # Test pull locally docker pull registry.example.com/myorg/myimage:latest echo $? # Should be 0

# For Kubernetes, verify pods start kubectl get pods -n my-namespace -w

# Check pod events kubectl describe pod my-pod -n my-namespace | grep -A 10 Events

# Verify image exists in the pod kubectl exec -it my-pod -n my-namespace -- ls -la /app ```

Prevention

To prevent Docker image pull authentication issues:

  1. 1.Use consistent registry hostnames: Standardize how registry addresses are referenced across all configurations and documentation.
  2. 2.Automate credential refresh: For cloud registries, use credential helpers instead of static credentials. Set up automated token refresh in CI/CD pipelines.

```yaml # GitHub Actions example for ECR - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1

  • name: Build and push
  • env:
  • REGISTRY: ${{ steps.login-ecr.outputs.registry }}
  • run: |
  • docker build -t $REGISTRY/myrepo:latest .
  • docker push $REGISTRY/myrepo:latest
  • `
  1. 1.Monitor credential expiration: Set up alerts for credential expiration, especially for tokens with limited lifespans.
  2. 2.Use Kubernetes secrets from external sources: For production, consider external secret operators that sync credentials from vaults or cloud providers.
yaml
# External Secrets Operator example
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: ecr-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets
    kind: ClusterSecretStore
  target:
    name: ecr-secret
    template:
      type: kubernetes.io/dockerconfigjson
  data:
    - secretKey: .dockerconfigjson
      remoteRef:
        key: ecr-credentials
  1. 1.Document registry access requirements: Clearly document which teams have access to which registries and repositories, and how to obtain access.
  2. 2.Test authentication in CI before deployment: Add a verification step that tests image pull authentication before deploying workloads.
  • [Fix docker build cache invalidated unnecessary layers Issue in Docker-Errors](docker-build-cache-invalidated-unnecessary-layers)
  • [Fix Docker Build Cache Invalidation Optimization Issue in Docker](docker-build-cache-invalidation-optimization)
  • [Fix docker build context slow large files Issue in Docker-Errors](docker-build-context-slow-large-files)
  • [Fix docker build multi stage copy from not found Issue in Docker-Errors](docker-build-multi-stage-copy-from-not-found)
  • [Fix docker buildkit export local tar layer missing Issue in Docker-Errors](docker-buildkit-export-local-tar-layer-missing)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Docker Image Pull Failed With Unauthorized Authentication Required", "description": "Resolve Docker image pull unauthorized errors by verifying registry login, image path access, credential helpers, and Kubernetes image pull secret configuration.", "url": "https://www.fixwikihub.com/docker-image-pull-unauthorized-authentication-required", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-01-23T08:44:56.235Z", "dateModified": "2026-01-23T08:44:56.235Z" } </script>