Bitbucket Pipelines: "You have reached your pull rate limit"
A step fails while Docker pulls an image from Docker Hub. On a self-hosted runner, with a pipe, the log reads (from a report in Atlassian's community):
Unable to find image 'bitbucketpipelines/ssh-run:0.4.1' locally docker: Error response from daemon: toomanyrequests: You have reached your pull rate limit.
Docker's own wording continues "You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limits" (Troubleshoot Docker Hub). Docker Hub counted the pulls and said no; nothing is wrong with the build itself.
Docker Hub's limits, and why Pipelines reaches them
Pulls per 6 hours (Docker Hub usage and limits):
- Not logged in: 100 per IPv4 address or IPv6 /64 subnet.
- Logged in with a Docker Personal account: 200.
- Docker Pro, Team and Business: unlimited.
A pull of a normal image is one pull; a multi-architecture image counts one pull per architecture; a version check that downloads nothing does not count. Atlassian's Docker Hub IP rate limiting (March 2025): Pipelines runs on a pool of shared IP ranges, so anonymous pulls share their limit with other people's builds. Logging in moves the limit from the IP address to your account.
- Atlassian's cloud: Pipelines keeps a mirror of the public layers on Docker Hub to avoid the limits where it can, and still asks you to log in, because many images extend others (Rate limiting with different third-party providers).
- Self-hosted runners: the pulls come from the runner host's public IP address and do not go through Atlassian. Runners that share one public address share the 100.
Log in for every kind of pull
A step can pull from Docker Hub in three places, and each logs in on its own. Put the Docker Hub user name and a Docker personal access token in secured repository or workspace variables. Atlassian's example:
definitions:
services:
my-service-name:
image:
name: alpine:latest
username: $DOCKER_USERNAME
password: $DOCKER_PASSWORD
pipelines:
default:
- step:
image:
name: customers_image_name
username: $DOCKER_USERNAME
password: $DOCKER_PASSWORD
services:
- my-service-name
script:
- docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
- The build image (
image:of the step or of the file):usernameandpasswordunder it (Use Docker images as build environments). - Service containers under
definitions: services:: the same two lines in theirimage:. - Pipes,
docker pull,docker runanddocker buildin the script:docker loginfirst, in the step. A pipe is an image too, pulled when the step reaches it.
A Personal account still stops at 200 per 6 hours. Only a paid Docker plan removes the limit.
See how many pulls are left
Docker's Pull usage and limits page gives a check that does not use up a pull: get a token, then send a HEAD request for a test image's manifest:
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token) curl --head -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest
The answer has ratelimit-limit: 100;w=21600 (100 per 21,600 seconds) and ratelimit-remaining. Run it in a step to check from the build's own address (docker-ratelimit-source shows it). For your account, get the token with curl --user 'username:password'.
A plain "Too Many Requests" is a different limit
Docker Hub's abuse limit answers 429 Too Many Requests with no further text. It is counted per IP address, in the thousands of requests a minute, for every account, logged in or not. Docker warns that platforms pulling for many users from one address can reach it. Docker's advice: fix CI pipelines that keep failing and calling Docker Hub, and retry with back-off.
Another registry
Atlassian's article reminds that the images need not come from Docker Hub. Bitbucket has its own container registry, Bitbucket Packages (crg.apkg.io/<workspace>/<image>), which a step logs in to with $BITBUCKET_PACKAGES_USERNAME and $BITBUCKET_PACKAGES_TOKEN (Working with the container registry). Amazon ECR, Google's registries and others work with the image: forms in Atlassian's build environment page.
See the failed pull from IntelliJ IDEA
Pipeline Inbox for Bitbucket Pipelines, a plugin by Lesstep for JetBrains IDEs 2024.1 or later, lists the pipelines of all your Bitbucket Cloud repositories in an IDE tool window. For a failed pipeline it shows the command the step failed at and that command's last lines, such as Docker's "toomanyrequests". The limit counts over 6 hours, so a build that only hit it can pass later without any change: with Pro, Run again builds the same commit once more from the IDE. The list, steps and logs are free; running, re-running and stopping pipelines are Pro (US$1.50 a month, with a 30-day trial).
Get it on JetBrains Marketplace
Atlassian, Bitbucket and Bitbucket Pipelines are trademarks of Atlassian; Docker is a trademark of Docker, Inc.; IntelliJ IDEA is a trademark of JetBrains s.r.o. This page is not affiliated with or endorsed by any of them.
More: Build setup takes too long · "No online runner available" · "Container 'docker' exceeded memory limit." · The build passed before and fails now · Re-running a failed pipeline · "There is an error in your bitbucket-pipelines.yml" · "This pipeline was paused" (deployments) · Bitbucket Pipelines plugins for IntelliJ IDEA, compared · 日本語