docker compose pull (and the implicit pull in up) fetches every service image. Any one of those pulls can hit a Hub rate limit or a registry 5xx - a transient failure, not a compose bug.
What this error means
docker compose up/pull fails while fetching one service’s image with toomanyrequests or received unexpected HTTP status: 5xx. Re-running often succeeds once the limit resets or the registry recovers.
docker compose output
db Pulling
db Error toomanyrequests: You have reached your pull rate limit.
Error response from daemon: ... pull rate limit
Common causes
Anonymous pulls share a Hub rate limit
Compose pulls several base images; unauthenticated on a shared CI IP, the combined pulls hit Docker Hub’s anonymous rate limit quickly.
Registry-side 5xx during a pull
A transient registry outage can fail one image pull mid-up, aborting the whole compose start even though the file is fine.
How to fix it
Authenticate and pull before up
Log in, then pull images as a separate retryable step so up does not re-fetch.
.github/workflows/test.yml
echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdinfor i in 1 2 3; do docker compose pull && break; sleep $((i*10)); donedocker compose up -d --no-build
Mirror or cache compose images
Pull service base images from a registry you control or a pull-through cache.
Pin image digests so cached layers are reused across runs.
Cache images between jobs to avoid re-pulling on every run.
How to prevent it
Authenticate to Docker Hub before any compose pull in CI.
Mirror compose service images into your own registry.
Wrap compose pull in a bounded retry with backoff.
Frequently asked questions
What causes ""compose pull" failed"?
Compose pulls several base images; unauthenticated on a shared CI IP, the combined pulls hit Docker Hub’s anonymous rate limit quickly.
How do I fix "compose pull" failed?
Log in, then pull images as a separate retryable step so up does not re-fetch.
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.