Skip to content
Latchkey

Terraform "Failed to retrieve available versions" registry 403 in CI

During init, Terraform queried the module registry for the available versions of a module and got an HTTP 403. The registry reached, but refused the request: either rate limiting or a credentials issue for a protected module.

What this error means

terraform init stops with "Error: Failed to retrieve available versions for module ..." and an HTTP 403 (Forbidden) from registry.terraform.io.

Terraform
Error: Failed to retrieve available versions for module "network"

Could not retrieve the list of available versions for module network from
registry.terraform.io: error looking up module versions: 403 Forbidden.

Common causes

Rate limiting from many concurrent CI jobs

A burst of parallel init calls from the same egress IP can trip the public registry rate limit and return 403.

A protected module without credentials

The module requires authentication the runner did not send, so the registry forbids the version listing.

How to fix it

Retry and reduce concurrent init pressure

  1. Re-run init: a rate-limit 403 usually clears on the next attempt.
  2. Serialize or cache module installs so fewer registry queries hit at once.
  3. Cache .terraform between runs so repeat jobs skip the lookup.
.github/workflows/ci.yml
- uses: actions/cache@v4
  with:
    path: .terraform
    key: tf-${{ hashFiles('.terraform.lock.hcl', '**/*.tf') }}

Provide credentials for a protected module

If the module is not public, add a registry token via a credentials block or TF_TOKEN_ env var.

.github/workflows/ci.yml
env:
  TF_TOKEN_registry_terraform_io: ${{ secrets.TF_REGISTRY_TOKEN }}

How to prevent it

  • Cache .terraform so parallel jobs do not re-query the registry.
  • Throttle concurrent inits sharing one egress IP.
  • Set a registry token for non-public modules.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →