Skip to content
Latchkey

Docker "unauthorized: authentication required" - Fix Registry Auth

The registry challenged the client for credentials and got none it would accept. Either there was no login, the token expired, or it lacks scope for this repository.

What this error means

A docker push or pull against a private registry stops with unauthorized: authentication required. Unlike a transient 5xx, this repeats every run until the credentials are fixed.

docker push/pull output
unauthorized: authentication required
# or, with more detail from the auth flow:
denied: requested access to the resource is denied
unauthorized: authentication required

Common causes

No login, or login ran in a different step/shell

docker login writes credentials to a config file for the current Docker context. If the login happened in a separate job, container, or with a different DOCKER_CONFIG, the pushing step has no credentials.

Expired or revoked token

Short-lived registry tokens (cloud provider tokens, OIDC-minted tokens, ECR get-login-password) expire. A login done long before the push can be stale by the time the push runs.

Token lacks scope for the target repository

A token valid for read may not grant push, or it may be scoped to a different namespace than the one you are writing to.

How to fix it

Log in immediately before the push

Keep the login and the push in the same job so the credentials are fresh and in scope.

Terminal
aws ecr get-login-password --region us-east-1 \
  | docker login --username AWS --password-stdin \
      123456789012.dkr.ecr.us-east-1.amazonaws.com
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/api:1.4.2

Use a token with write scope

  1. For GHCR, give the workflow packages: write permission (or use a PAT with write:packages).
  2. For Docker Hub, create an access token with Read & Write, not Read-only.
  3. For cloud registries, ensure the CI role has push (e.g. ECR BatchCheckLayerAvailability + PutImage).

How to prevent it

  • Mint or refresh registry tokens in the same job that pushes.
  • Grant the minimum scope that still includes push for the target repository.
  • Avoid sharing a login across jobs; re-authenticate per job.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →