cargo "429 Too Many Requests" from crates.io in CI
crates.io returned HTTP 429, meaning the runner sent more requests than the registry allows in a window. This is a transient rate limit, common from shared CI egress IPs, not a problem with your dependencies.
What this error means
cargo fetch or build fails with "error: failed to download from ..." and a "429 Too Many Requests" status while downloading crates or updating the index.
error: failed to download from `https://static.crates.io/crates/serde/serde-1.0.203.crate`
Caused by:
failed to get successful HTTP response from `https://static.crates.io/...`, got 429
body:
Too Many RequestsCommon causes
Shared CI egress IP hit the rate limit
Many jobs from the same hosted-runner IP range share a quota, so a burst of downloads can trip the limit even for a small project.
No caching, so every run re-downloads everything
Without a crate cache, each job fetches the full dependency set, multiplying requests and the chance of a 429.
How to fix it
Cache the cargo registry and retry
Persist the registry and git caches so most crates are already present and only deltas are fetched.
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: cargo-${{ hashFiles('Cargo.lock') }}Use a sparse index and back off on retry
The sparse protocol fetches only needed index files; re-running the job after a short wait usually clears a transient 429.
CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse cargo fetch --lockedHow to prevent it
- Cache
~/.cargo/registryand~/.cargo/gitacross runs. - Use the sparse index to cut request volume.
- Pin
Cargo.lockso only required crates are fetched.