Testcontainers "pull access denied" / Docker Hub rate limit in CI
Testcontainers pulls the images your tests need, and on shared CI IPs anonymous Docker Hub pulls hit the rate limit or private images return "pull access denied". Authenticating to the registry fixes both.
What this error means
Setup fails while pulling an image with "pull access denied for X, repository does not exist or may require 'docker login'" or "toomanyrequests: You have reached your pull rate limit".
Caused by: com.github.dockerjava.api.exception.DockerClientException:
Could not pull image: toomanyrequests: You have reached your pull rate limit.
You may increase the limit by authenticating and upgradingCommon causes
Anonymous pulls share the runner IP rate limit
Hosted runners share outbound IPs, so unauthenticated Docker Hub pulls exhaust the anonymous rate limit quickly.
The image is private and login is missing
"pull access denied" for a private repository means Docker is not logged in to a registry that can read it.
How to fix it
Log in to the registry before tests
Authenticate to Docker Hub (or your registry) so pulls use your higher authenticated limits and can read private images.
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}Pull from a mirror or cache
Point Testcontainers images at an authenticated registry mirror so repeated CI runs avoid the anonymous limit.
How to prevent it
- Authenticate to Docker Hub in CI to raise pull limits and read private images.
- Mirror or cache frequently pulled images to reduce registry hits.
- Store registry credentials in CI secrets, never in the workflow file.