Fix: Terraform Failed to install provider (or Failed to query available provider packages)

The Error

You run terraform init and get:

Error: Failed to install provider

Error while installing hashicorp/aws v5.40.0: could not query provider
registry for registry.terraform.io/hashicorp/aws: failed to retrieve
authentication checksums for provider

Or one of these variations:

Error: Failed to query available provider packages

Could not retrieve the list of available versions for provider
hashicorp/aws: could not connect to registry.terraform.io
Error: Failed to install provider from shared cache

The provider registry.terraform.io/hashicorp/aws 5.40.0 is not available
for the current platform windows_arm64
Error: Incompatible provider version

Provider registry.terraform.io/hashicorp/random v2.3.0 does not have a
package available for your current platform, darwin_arm64
Error: Failed to query available provider packages

Could not retrieve the list of available versions for provider
mycorp/custom: provider registry registry.terraform.io does not have a
provider named registry.terraform.io/mycorp/custom
Error: Failed to install providers

Could not find required providers, but found possible alternatives:

  hashicorp/aws -> registry.terraform.io/hashicorp/aws

All of these relate to Terraform’s provider installation mechanism — the process that downloads and verifies provider plugins during terraform init.

Why This Happens

Terraform providers are plugins that let Terraform interact with APIs — AWS, Azure, GCP, Kubernetes, Docker, and hundreds more. When you run terraform init, Terraform reads your configuration, determines which providers are needed, and downloads them from a provider registry (by default, registry.terraform.io).

The “Failed to install provider” family of errors means one of these things:

  • Terraform can’t reach the registry. Network issues, proxy misconfiguration, DNS failures, or firewall rules are blocking outbound HTTPS connections to registry.terraform.io.
  • The provider version you requested doesn’t exist. Your version constraint is too strict, or the provider has been yanked or renamed.
  • The provider doesn’t have a build for your platform. You’re on Apple Silicon (darwin_arm64), ARM Linux, or another architecture the provider author hasn’t published binaries for.
  • Your required_providers block is missing or wrong. Since Terraform 0.13, third-party providers need an explicit source address. Without it, Terraform assumes hashicorp/PROVIDERNAME and fails when it doesn’t find it.
  • The lock file conflicts with your constraints. Your .terraform.lock.hcl has pinned a version that no longer satisfies your version constraints after a configuration change.
  • You’re in an air-gapped or restricted environment. Corporate networks, CI runners without internet, or hardened production environments can’t reach the public registry.

Understanding which category your error falls into will point you to the right fix below.

Fix 1: Run terraform init (or Re-run It)

The most basic cause: you haven’t initialized the working directory, or a previous init was interrupted.

terraform init

If you’ve already initialized but changed provider requirements, re-run init. Terraform will detect the changes and download what’s needed.

If init was previously interrupted (Ctrl+C, network drop, CI timeout), the .terraform directory may be in a partial state. Clean it and start over:

rm -rf .terraform
terraform init

This removes all cached providers and modules, forcing a clean download. Your state file (local or remote) is not affected — only the local plugin cache is deleted.

If your terraform init fails in a CI/CD pipeline, make sure the runner has outbound internet access. See Fix: Process completed with exit code 1 (GitHub Actions) for general CI debugging tips.

Fix 2: Loosen Version Constraints That Are Too Strict

If the error message says something like “no available releases match the given constraints,” your version constraint is filtering out every published version.

Check your required_providers block:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "= 5.37.0"  # exact pin -- fails if this version is yanked
    }
  }
}

An exact version pin (= 5.37.0) fails if that specific version is removed from the registry. A too-narrow range (>= 5.37.0, < 5.38.0) fails if no version exists within that window.

Use flexible constraints

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"    # allows 5.x.x but not 6.0.0
    }
  }
}

The ~> operator (pessimistic constraint) is the standard approach. ~> 5.0 allows any 5.x release. ~> 5.40 allows 5.40.x but not 5.41.0.

After changing constraints, upgrade the lock file:

terraform init -upgrade

The -upgrade flag tells Terraform to re-resolve versions within your new constraints, ignoring what’s in .terraform.lock.hcl.

Check what versions actually exist

You can browse the Terraform registry to see available versions, or query the API:

curl -s "https://registry.terraform.io/v1/providers/hashicorp/aws/versions" | python3 -m json.tool | head -50

Fix 3: Add the Provider Source (Terraform 0.13+ required_providers)

Terraform 0.13 introduced a new syntax for declaring providers. Before 0.13, Terraform inferred the source from the provider name. After 0.13, you need an explicit source attribute for any non-HashiCorp provider.

If you see:

Could not find required providers, but found possible alternatives:

  hashicorp/datadog -> registry.terraform.io/DataDog/datadog

Terraform is looking for hashicorp/datadog but the provider is published under DataDog/datadog. Fix it by specifying the source:

terraform {
  required_providers {
    datadog = {
      source  = "DataDog/datadog"
      version = "~> 3.0"
    }
  }
}

This applies to all third-party providers — anything not published by HashiCorp. Common examples:

terraform {
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 4.0"
    }
    datadog = {
      source  = "DataDog/datadog"
      version = "~> 3.0"
    }
    mongodbatlas = {
      source  = "mongodb/mongodbatlas"
      version = "~> 1.0"
    }
  }
}

After adding the source, run:

terraform init

If you’re upgrading an older project from Terraform 0.12, run terraform 0.13upgrade to automatically add required_providers blocks based on your existing configuration.

Fix 4: Fix Network and Proxy Issues

If Terraform can’t reach registry.terraform.io, you’ll see connection errors, timeouts, or TLS failures.

Test connectivity

curl -I https://registry.terraform.io

If this times out or returns an error, you have a network-level problem.

Configure proxy settings

Terraform respects the standard HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables:

export HTTPS_PROXY=http://corporate-proxy.example.com:8080
export NO_PROXY=localhost,127.0.0.1,internal.example.com
terraform init

On Windows:

$env:HTTPS_PROXY = "http://corporate-proxy.example.com:8080"
$env:NO_PROXY = "localhost,127.0.0.1,internal.example.com"
terraform init

If you’re consistently having trouble with environment variables not being picked up, see Fix: process.env.VARIABLE_NAME Is Undefined — while that article focuses on Node.js, the mental model for debugging environment variable issues is the same across tools.

TLS certificate issues

Corporate proxies often perform TLS inspection, injecting their own CA certificate. Terraform’s built-in TLS verification will reject these. You can point Terraform to your corporate CA bundle:

export SSL_CERT_FILE=/path/to/corporate-ca-bundle.crt
terraform init

Or on a per-host basis in your Terraform CLI configuration (~/.terraformrc or %APPDATA%\terraform.rc):

host "registry.terraform.io" {
  services = {
    "providers.v1" = "https://registry.terraform.io/v1/providers/"
  }
}

DNS resolution failures

If DNS is the problem, verify you can resolve the registry hostname:

nslookup registry.terraform.io

If your DNS server is blocking or failing, try using a public DNS temporarily, or ask your network administrator to allowlist registry.terraform.io and releases.hashicorp.com.

Fix 5: Fix Mirror or Registry Configuration

If you’ve configured a provider mirror or alternative registry in your Terraform CLI configuration, a misconfiguration there can cause install failures.

Check your CLI configuration

Look at ~/.terraformrc (Linux/macOS) or %APPDATA%\terraform.rc (Windows):

provider_installation {
  filesystem_mirror {
    path    = "/usr/share/terraform/providers"
    include = ["registry.terraform.io/*/*"]
  }
  direct {
    exclude = ["registry.terraform.io/*/*"]
  }
}

This configuration tells Terraform to look in a local directory first and never go to the internet. If the mirror is missing the provider you need, Terraform fails instead of falling back.

Fix: Allow direct fallback

provider_installation {
  filesystem_mirror {
    path    = "/usr/share/terraform/providers"
    include = ["registry.terraform.io/*/*"]
  }
  direct {}  # fallback to direct download for anything not in mirror
}

The empty direct {} block acts as a fallback — if the mirror doesn’t have it, Terraform downloads directly from the registry.

Network mirrors

If you’re using a network mirror:

provider_installation {
  network_mirror {
    url = "https://terraform-mirror.example.com/providers/"
  }
}

Verify the mirror URL is reachable and serves the providers you need:

curl -s "https://terraform-mirror.example.com/providers/registry.terraform.io/hashicorp/aws/index.json"

Fix 6: The Provider Doesn’t Exist or Has Been Renamed

Sometimes the provider name is simply wrong, or the provider has been moved to a different namespace.

Common mistakes

  • Typo in the source: hashcorp/aws instead of hashicorp/aws
  • Using the old name after a rename: Some providers change namespaces when organizations restructure
  • Assuming a provider exists: Not every service has a Terraform provider in the public registry

Search the registry

Go to registry.terraform.io and search for the provider. If it’s been renamed, the old namespace usually shows a redirect notice.

If the provider is community-maintained and has been abandoned, you may need to fork it or find an alternative. Check the provider’s GitHub repository for recent activity.

Fix 7: Platform Not Supported (M1/M2 Mac, ARM, Windows ARM)

When Apple released M1 Macs with ARM architecture (darwin_arm64), many Terraform providers initially lacked ARM builds. The same applies to ARM-based Linux servers and Windows ARM devices.

The error looks like:

Provider registry.terraform.io/hashicorp/template v2.2.0 does not have a
package available for your current platform, darwin_arm64

Check what platforms are available

curl -s "https://registry.terraform.io/v1/providers/hashicorp/template/2.2.0/download/darwin/arm64"

A 404 response confirms the platform isn’t supported.

Workarounds

Use Rosetta 2 (macOS Apple Silicon):

Install the AMD64 version of Terraform under Rosetta:

# Install AMD64 Terraform via Homebrew
arch -x86_64 brew install terraform

This runs Terraform in x86 emulation mode, which can use darwin_amd64 provider binaries. It’s slower but works for all providers.

Use a replacement provider:

The hashicorp/template provider is the most common offender — it’s archived and won’t receive ARM builds. Use the built-in templatefile() function instead:

# Instead of this (template provider):
data "template_file" "init" {
  template = file("${path.module}/init.tpl")
  vars = {
    consul_address = aws_instance.consul.private_ip
  }
}

# Use this (built-in function):
locals {
  init_script = templatefile("${path.module}/init.tpl", {
    consul_address = aws_instance.consul.private_ip
  })
}

Build the provider from source:

If the provider is open-source and you have Go installed:

git clone https://github.com/hashicorp/terraform-provider-example.git
cd terraform-provider-example
go build -o terraform-provider-example

Then place the binary in the correct local directory structure (see Fix 9 below).

Fix 8: Resolve .terraform.lock.hcl Conflicts

The .terraform.lock.hcl file records the exact provider versions and their platform-specific checksums. Conflicts arise when:

  • Different team members use different platforms. The lock file initially only contains checksums for the platform that ran terraform init. When a teammate on a different OS tries to init, the checksums don’t match.
  • You changed version constraints but didn’t update the lock file.
  • You merged branches with different lock file contents.

Update checksums for multiple platforms

terraform providers lock \
  -platform=linux_amd64 \
  -platform=darwin_amd64 \
  -platform=darwin_arm64 \
  -platform=windows_amd64

This updates .terraform.lock.hcl with checksums for all specified platforms. Run this once and commit the result — now any team member on any of these platforms can run terraform init without checksum mismatches.

Force re-resolution

If the lock file is hopelessly conflicted (e.g., after a bad merge), delete it and regenerate:

rm .terraform.lock.hcl
terraform init

Then regenerate with multi-platform support as shown above, and commit the new lock file.

Should you commit .terraform.lock.hcl?

Yes. HashiCorp recommends committing this file. It ensures every team member and CI pipeline uses the exact same provider versions. Without it, terraform init might resolve different versions for different people, leading to inconsistent behavior. For related state lock issues when collaborating on Terraform projects, see Fix: Error Acquiring the State Lock (Terraform).

Fix 9: Install Custom or Third-Party Providers Manually

Not all providers are in the public registry. Internal or custom providers need to be installed manually.

Local filesystem installation

Place the provider binary in Terraform’s local plugin directory following this structure:

~/.terraform.d/plugins/
  example.com/
    mycorp/
      myprovider/
        1.0.0/
          linux_amd64/
            terraform-provider-myprovider_v1.0.0

The directory structure encodes the provider source, version, and platform. The source address in your configuration must match:

terraform {
  required_providers {
    myprovider = {
      source  = "example.com/mycorp/myprovider"
      version = "1.0.0"
    }
  }
}

Using dev_overrides for development

When developing a provider locally, use dev_overrides in your CLI configuration to point Terraform at a local binary without the full directory structure:

# ~/.terraformrc
provider_installation {
  dev_overrides {
    "example.com/mycorp/myprovider" = "/home/user/go/bin"
  }
  direct {}
}

With dev_overrides, you skip terraform init entirely for that provider. Terraform uses the binary directly from the specified path.

Private registries

If your organization runs a private Terraform registry, configure it in your CLI config:

credentials "terraform.example.com" {
  token = "your-api-token"
}

Then reference providers from your private registry:

terraform {
  required_providers {
    internal = {
      source  = "terraform.example.com/mycorp/internal"
      version = "~> 2.0"
    }
  }
}

Fix 10: Air-Gapped and Restricted Environments

In environments with no internet access (government, banking, high-security production), you need to pre-download providers and serve them locally.

Create a provider bundle

On a machine with internet access, create a mirror of the providers you need:

terraform providers mirror /path/to/mirror

This downloads all providers required by the current configuration (with binaries for your current platform) into the specified directory.

For multiple platforms:

terraform providers mirror -platform=linux_amd64 -platform=darwin_arm64 /path/to/mirror

Transfer and configure

Copy the mirror directory to your air-gapped machine. Then configure Terraform to use it:

# ~/.terraformrc on the air-gapped machine
provider_installation {
  filesystem_mirror {
    path = "/opt/terraform/providers"
  }
}

Now terraform init reads from the local mirror instead of reaching out to the internet.

Bundle for CI/CD

For CI pipelines in restricted environments, include the provider mirror in your container image or artifact storage:

FROM hashicorp/terraform:1.9

COPY provider-mirror/ /opt/terraform/providers/

RUN cat <<'EOF' > /root/.terraformrc
provider_installation {
  filesystem_mirror {
    path = "/opt/terraform/providers"
  }
}
EOF

This ensures your CI pipeline never needs to reach the public registry at runtime. If your CI pipeline is failing for other reasons, check your workflow configuration — see Fix: Process completed with exit code 1 (GitHub Actions) for debugging GitHub Actions failures specifically.

Network mirror for shared teams

If multiple teams need provider access in a restricted network, set up a network mirror instead of giving everyone a filesystem copy:

# Serve the mirror directory over HTTP
cd /path/to/mirror
python3 -m http.server 8080

Then configure all clients:

provider_installation {
  network_mirror {
    url = "http://internal-mirror.example.com:8080/"
  }
}

For production use, put a proper web server (nginx, Artifactory, Nexus) in front of the mirror directory with TLS and authentication.

Still Not Working?

The error mentions “checksum mismatch”

Error: Failed to install provider

The current package for registry.terraform.io/hashicorp/aws 5.40.0 doesn't
match any of the checksums previously recorded in the dependency lock file.

This means the provider binary you’re downloading doesn’t match the checksum in .terraform.lock.hcl. This can happen when:

  • The registry was compromised (extremely rare, but the check exists for this reason). Verify with HashiCorp if you suspect this.
  • A proxy or cache is serving stale or modified content. Corporate proxies, CDN caches, or Artifactory instances can sometimes serve corrupted or outdated files.
  • You’re mixing platform checksums. Run terraform providers lock with all platforms your team uses (see Fix 8).

To force a fresh download with new checksums:

rm .terraform.lock.hcl
rm -rf .terraform
terraform init

Then regenerate multi-platform checksums and commit.

terraform init hangs indefinitely

If init doesn’t error but never completes, it’s likely a network issue where the connection is established but the download stalls. Common causes:

  • Slow or unstable proxy. Try bypassing the proxy temporarily to confirm.
  • MTU issues on VPN connections. Lower your MTU or use a different VPN protocol.
  • Rate limiting. The Terraform registry rate-limits aggressive downloads. Wait and retry.

Set TF_LOG=DEBUG to see exactly where Terraform is stuck:

export TF_LOG=DEBUG
terraform init 2>&1 | tee terraform-init-debug.log

Provider works locally but fails in CI

Your local machine can reach the registry, but your CI runner can’t. Check:

  1. Firewall rules on the CI runner — does it allow outbound HTTPS to registry.terraform.io and releases.hashicorp.com?
  2. Docker networking — if Terraform runs inside a container, does the container have DNS and internet access?
  3. Credentials for private registries — are they set in the CI environment? If your CI uses AWS and you’re also having credential issues, see Fix: Unable to Locate Credentials (AWS CLI / SDK).
  4. Disk space — provider binaries can be large (the AWS provider is over 400 MB). CI runners with small ephemeral disks can run out of space.

Multiple providers with the same type name

If you’re using two providers that provide the same resource type (e.g., two different Kubernetes providers), you’ll get conflicts. Use provider aliases:

provider "kubernetes" {
  alias  = "cluster1"
  config_path = "~/.kube/config-cluster1"
}

provider "kubernetes" {
  alias  = "cluster2"
  config_path = "~/.kube/config-cluster2"
}

resource "kubernetes_namespace" "example" {
  provider = kubernetes.cluster1
  metadata {
    name = "example"
  }
}

Configuration files have syntax errors preventing provider resolution

Terraform parses all .tf files before resolving providers. If any file has a syntax error, terraform init can fail before even attempting to download providers. The error might mention providers but the root cause is a syntax issue. Run terraform validate to check, and if you’re dealing with tricky YAML or HCL formatting problems, see Fix: YAML Mapping Values Are Not Allowed Here for a similar debugging approach.


Related: If your Terraform AWS operations fail with credential errors, see Fix: Unable to Locate Credentials (AWS CLI / SDK). For Terraform state lock problems, see Fix: Error Acquiring the State Lock (Terraform).

Related Articles