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

Docker Error Guide: 'unauthorized: authentication required' — Fix Docker Login and Tokens

Quick answer

Fix Docker 'unauthorized: authentication required': log in to the right registry, refresh expired tokens, handle rate limits, and configure non-interactive CI credentials correctly.

Part of the Docker Build & Image Errors hub
  • #docker
  • #troubleshooting
  • #errors
  • #authentication
Free toolkit

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 returns this on pull or push when the registry needs valid credentials and did not get any it accepts:

unauthorized: authentication required

Unlike an authorization denied, this is an authentication failure: the registry could not verify who you are. You are either not logged in, your token has expired, or the credentials Docker sent were rejected. On Docker Hub it also appears when an anonymous pull rate limit is hit and the registry demands you authenticate.

Symptoms

  • docker pull or docker push ends in unauthorized: authentication required.
  • Pulls that worked yesterday fail today (token expired or rate limit reached).
  • CI fails to pull a private base image while your laptop succeeds.
  • docker login reports success but subsequent commands still say unauthorized (credentials stored for the wrong registry host).

Common Root Causes

  • Not logged in — no credentials for the target registry in ~/.docker/config.json.
  • Expired or revoked token — a time-limited access token or session has lapsed.
  • Wrong registry host — logged into Docker Hub but pulling from registry.example.com, or vice versa.
  • Docker Hub rate limits — anonymous or free-tier pull limits reached; the registry forces authentication.
  • Incorrect credentials in CI — wrong username/token, or a secret not exposed to the job.
  • Credential helper not returning the token — a misconfigured credsStore returns nothing.

Diagnostic Workflow

See which registries you currently have credentials for:

cat ~/.docker/config.json      # look for the target host under "auths"

Log in explicitly to the exact registry host in the image reference:

docker login registry.example.com
# for Docker Hub, the host is docker.io (docker login with no host)

In CI, authenticate non-interactively so tokens never touch the shell history:

echo "$REGISTRY_TOKEN" | docker login registry.example.com -u ci-bot --password-stdin

Retry the operation and, if it still fails, confirm you are not hitting a Docker Hub rate limit:

docker pull registry.example.com/myteam/myapp:1.4.2
journalctl -u docker --since '5 min ago' | grep -i 'unauthorized\|rate\|toomanyrequests'

If login succeeds but pulls still fail, the credential store may not be returning the token — check the configured helper:

docker-credential-$(grep -o '"credsStore": *"[^"]*"' ~/.docker/config.json | cut -d'"' -f4) list

Example Root Cause Analysis

A nightly build began failing with unauthorized: authentication required when pulling a private base image registry.example.com/myteam/base:1.4.2. The same pull worked interactively for engineers.

cat ~/.docker/config.json on the CI runner showed an auths entry for docker.io but none for registry.example.com. The pipeline had run docker login with no host, authenticating to Docker Hub instead of the private registry that actually held the image.

The fix was to log in to the correct host with a scoped robot token via stdin:

echo "$REGISTRY_TOKEN" | docker login registry.example.com -u ci-bot --password-stdin
docker pull registry.example.com/myteam/base:1.4.2

With credentials stored under the right host, the pull succeeded. Had the cause been Docker Hub instead, the same authenticated login would also lift the anonymous rate limit.

Prevention Best Practices

  • Always docker login to the exact host in your image references; remember that Docker Hub’s host is docker.io.
  • Use scoped robot/service tokens with --password-stdin in CI and store them as protected secrets.
  • Rotate and refresh time-limited tokens before they expire; add a login step at the start of every pipeline.
  • Authenticate to Docker Hub even for public pulls to avoid anonymous rate limits on busy build fleets.
  • Standardize registry auth across environments using the Docker stack guide and validate builds with the Dockerfile validator.

Quick Command Reference

cat ~/.docker/config.json                     # which hosts have creds?
docker login registry.example.com            # authenticate to the right host
echo "$REGISTRY_TOKEN" | docker login registry.example.com -u ci-bot --password-stdin
docker pull registry.example.com/myteam/myapp:1.4.2
journalctl -u docker --since '5 min ago' | grep -i 'unauthorized\|toomanyrequests'

Conclusion

unauthorized: authentication required means the registry could not verify your identity — you are not logged in, your token expired, or you authenticated to the wrong host. Check ~/.docker/config.json for the exact registry host, log in with a valid (ideally scoped) token via --password-stdin, and retry. On Docker Hub, authenticating also clears anonymous rate limits. Once the right credentials reach the right host, pulls and pushes proceed.

Free download · 368-page PDF

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.