Skip to content
Latchkey

Docker "registry-mirrors" Ignored or Unreachable - Pull-Through Cache Not Working in CI

A registry-mirrors entry in daemon.json sets a pull-through cache for Docker Hub. It is commonly ineffective: it only applies to Docker Hub images, only to anonymous pulls in some setups, and a typo or an unreachable mirror makes pulls quietly fall back to the upstream (and its rate limits).

What this error means

Pulls still hit Docker Hub (and its rate limit) despite a configured mirror, or pulls of non-Hub images ignore the mirror entirely. A docker info shows the mirror, but the cache is not being used as expected.

docker pull / docker info
# daemon.json had: { "registry-mirrors": ["https://mirror.example.com"] }
# yet pulls still fail with:
toomanyrequests: You have reached your pull rate limit
# (the mirror was unreachable, or the image was not a Docker Hub image)

Diagnose it: separate auth from naming from rate limits

Registry errors look alike and have unrelated causes. Work out which of the three you have before changing credentials, because a malformed image reference produces an error that reads like an authentication failure.

Terminal
# 1. is the reference even valid? (lowercase, no spaces, valid tag)
docker image inspect "$IMAGE" 2>&1 | head -2

# 2. are you authenticated to the right registry?
cat ~/.docker/config.json | grep -o '"[^"]*\.[^"]*"' | head

# 3. are you rate limited? (Docker Hub anonymous pulls)
curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimit-preview/test:pull" \
  | grep -o '"token"' >/dev/null && echo "token ok"

Common causes

Mirrors only apply to Docker Hub images

registry-mirrors is a pull-through cache for docker.io only. Images from GHCR, ECR, or other registries ignore the mirror entirely.

The mirror is unreachable or misconfigured

A typo, a wrong scheme/port, or a down mirror makes the daemon fall back to the upstream registry, so pulls still hit Hub and its limits.

Daemon not reloaded after editing daemon.json

Changes to registry-mirrors only take effect after a daemon restart. Without it, the running daemon still uses the old (or no) mirror.

How to fix it

Configure a reachable Hub mirror and restart

Point at a working pull-through cache for Docker Hub and reload the daemon.

daemon.json / Terminal
# /etc/docker/daemon.json
{ "registry-mirrors": ["https://mirror.example.com"] }

sudo systemctl restart docker
docker info | grep -A2 'Registry Mirrors'

Mirror non-Hub registries differently

  1. For GHCR/ECR/etc., pull through your cloud provider’s registry cache or copy images into your own registry.
  2. Confirm the mirror host is reachable from the runner network.
  3. Authenticate to Docker Hub as well - a mirror does not remove the auth-based rate limits.

Authenticate in the job, not in the image

.github/workflows/ci.yml
- uses: docker/login-action@v3
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

# GHCR needs this on the job or the push is rejected as unauthorised
permissions:
  contents: read
  packages: write

How to prevent it

  • Remember registry-mirrors only caches Docker Hub images.
  • Verify the mirror is reachable and restart the daemon after config changes.
  • Use provider-specific caches for non-Hub registries.

Frequently asked questions

What causes Docker "registry-mirrors" ignored or unreachable?
There are 3 common causes: mirrors only apply to docker hub images, the mirror is unreachable or misconfigured, and daemon not reloaded after editing daemon.json. registry-mirrors is a pull-through cache for docker.io only.
How do I fix Docker "registry-mirrors" ignored or unreachable?
There are 2 fixes depending on which cause you have: configure a reachable hub mirror and restart and mirror non-hub registries differently. Work through them in order, since the first is the most common.
What does Docker "registry-mirrors" ignored or unreachable actually mean?
Pulls still hit Docker Hub (and its rate limit) despite a configured mirror, or pulls of non-Hub images ignore the mirror entirely.
How do I stop Docker "registry-mirrors" ignored or unreachable happening again?
Remember registry-mirrors only caches Docker Hub images. The prevention section lists 3 changes that keep it from recurring.
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

This is a transient network failure, not a bug in your code. Latchkey detects, repairs, and retries it for you. Start free → 30-day trial · No credit card