Skip to content
Latchkey

Docker "--cache-to type=registry" Fails to Authenticate in CI

A registry-backed build cache (type=registry) is just another image in a registry, so exporting or importing it needs valid push/pull credentials for that cache reference. The cache step fails with unauthorized/denied when those credentials are missing or under-scoped.

What this error means

A docker buildx build with --cache-to type=registry,... or --cache-from type=registry,... fails the cache step with unauthorized / denied (export) or failed to configure registry cache (import). The image push itself may be fine; only the cache reference is rejected.

docker buildx output
ERROR: failed to solve: error writing cache to ghcr.io/myorg/api:buildcache:
unexpected status: 401 Unauthorized
# or on import: failed to configure registry cache importer: ... 403 Forbidden

Common causes

No login (or wrong scope) for the cache repository

Exporting cache writes to the registry, so the job needs write access to the cache ref. A read-only or missing login fails the --cache-to export with 401/403.

Cache ref points at a different registry/namespace

If the cache reference lives in a registry you did not authenticate to (or a namespace your token cannot write), the cache step is denied even when the main push works.

Transient registry 5xx during cache export

A registry blip while writing the cache manifest surfaces as a cache failure that often clears on retry.

How to fix it

Authenticate to the cache registry with write scope

Log in to the exact registry that holds the cache ref before building, with a token that can write it.

Terminal
echo "$TOKEN" | docker login ghcr.io -u "$USER" --password-stdin
docker buildx build \
  --cache-to type=registry,ref=ghcr.io/myorg/api:buildcache,mode=max \
  --cache-from type=registry,ref=ghcr.io/myorg/api:buildcache \
  --push -t ghcr.io/myorg/api:1.4.2 .

Make cache export non-fatal, retry transients

Treat a transient cache 5xx as retryable; keep the cache ref in a repo your token controls.

How to prevent it

  • Log in to the cache registry with write scope in the same job that builds.
  • Keep the cache ref in a registry/namespace your CI credentials own.
  • Wrap cache export in a bounded retry for transient registry 5xx.

Frequently asked questions

What causes ""cache export failed: unauthorized""?
Exporting cache writes to the registry, so the job needs write access to the cache ref. A read-only or missing login fails the --cache-to export with 401/403.
How do I fix "cache export failed: unauthorized"?
Log in to the exact registry that holds the cache ref before building, with a token that can write it.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card