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.
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 ForbiddenCommon 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.
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.