Skip to content

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

FixDevs · (Updated: )

Part of:  Docker, DevOps & Infrastructure

Quick Answer

How to fix 'Failed to install provider' and 'Failed to query available provider packages' errors in Terraform, covering registry issues, version constraints, network problems, platform support, and air-gapped environments.

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 HTTPS_PROXY is set in your interactive shell but not in the systemd unit, cron job, or CI job actually running Terraform, the registry call still fails. Use env | grep -i proxy from the same shell that invokes terraform init to confirm the variable is exported, not just assigned.

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.

Common Mistake: Setting HTTPS_PROXY but forgetting NO_PROXY causes Terraform to route registry.terraform.io through your corporate proxy, which may perform TLS inspection and reject the download checksums. Always add the Terraform registry to your NO_PROXY list if your proxy doesn’t need to inspect it.

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.

How other IaC tools handle providers

If you are evaluating a fork or a competitor because Terraform’s registry keeps failing, the model differs significantly across tools. Knowing how each one fetches and verifies plugins helps you pick the right escape hatch.

OpenTofu Registry. OpenTofu (the Linux Foundation fork after the BSL relicense) maintains its own registry at registry.opentofu.org. It mirrors most HashiCorp providers and accepts new submissions through a GitHub-based registry repo, so providers can be added without a private company gatekeeping the namespace. The CLI is a drop-in replacement: tofu init, tofu plan, tofu apply. The .terraform.lock.hcl file is fully compatible. If your “Failed to install provider” comes from registry.terraform.io rate-limiting your IP block, switching the source address to registry.opentofu.org/hashicorp/aws is the smallest possible change. State files are interchangeable in both directions for now, but that compatibility is not guaranteed long term.

Pulumi packages. Pulumi distributes providers as npm packages, Python wheels, NuGet packages, or Go modules, depending on your language. There is no central provider binary registry — npm install @pulumi/aws pulls a JavaScript wrapper plus a Go binary plugin via Pulumi’s plugin downloader. The equivalent failure looks like error: failed to download provider aws v6.0.0 or error: could not find latest version of plugin aws. Workarounds use pulumi plugin install resource aws 6.0.0 --file ./aws.tar.gz for air-gapped installs. For more on diagnosing Pulumi-side issues, see Fix: Pulumi not working.

Crossplane providers. Crossplane runs inside Kubernetes and installs providers as Provider CRDs that pull OCI images from a container registry (typically xpkg.upbound.io). “Failed to install provider” in Crossplane is really a Kubernetes image-pull failure on the provider pod. Debug with kubectl describe provider provider-aws and check the underlying ProviderRevision and DeploymentRuntimeConfig. There is no lock file — version pinning happens in the Provider manifest.

CDK for Terraform (CDKTF). CDKTF is a thin wrapper that generates cdk.tf.json and then invokes Terraform under the hood. Every provider install failure you see in plain Terraform also reproduces in CDKTF, plus a layer of JSII bindings (@cdktf/provider-aws) that you install via npm or pip. If cdktf get fails to generate bindings, the root cause is usually still a Terraform Registry call from inside the CDKTF binary — diagnose it with TF_LOG=DEBUG cdktf get.

Mirror configuration and checksums across tools. Terraform and OpenTofu share the filesystem_mirror / network_mirror syntax. Pulumi mirrors are configured through PULUMI_DOWNLOAD_URL for the plugin binary and npm config set registry for the wrapper. Crossplane uses imagePullSecrets and standard OCI registry credentials. All three verify checksums by default: Terraform via .terraform.lock.hcl SHA256s, Pulumi via its CDN plus signed manifests, and Crossplane via OCI image digests. Stripping any of these checks weakens supply-chain protection — favor a properly authenticated internal mirror over a --skip-checksum-style flag.

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 — the resulting diagnostic points to the line that prevented HCL parsing, not the provider itself.

Terraform CLI version is older than the provider’s required version

Providers declare a minimum Terraform CLI version in their manifest. If you pin aws ~> 5.80 while running Terraform 1.2, init can fail with “Provider requires Terraform >= 1.5” buried in the error chain. Check both sides:

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

Upgrade Terraform (tfenv install latest or tenv tf install) before chasing other causes.

Antivirus or EDR is quarantining the downloaded plugin binary

Provider binaries are large Go executables that some endpoint protection tools (CrowdStrike Falcon, Sophos, Defender for Endpoint) flag as suspicious and silently quarantine. terraform init then reports a checksum mismatch or “permission denied” because the file vanished mid-extract. Check the EDR quarantine log for entries under .terraform/providers/, and add an exclusion for the providers directory.

Provider binary architecture mismatch inside a container

On Apple Silicon, running an amd64 container that contains arm64 Terraform binaries (or vice versa) makes terraform init download the wrong-arch provider. Inspect with:

docker run --rm --platform=linux/amd64 hashicorp/terraform:1.9 version
file .terraform/providers/registry.terraform.io/hashicorp/aws/*/linux_amd64/terraform-provider-aws_v*

Pin --platform=linux/amd64 (or linux/arm64) consistently on the build, the run, and the Terraform -platform= lock arguments.

TF_PLUGIN_CACHE_DIR is on a read-only or mismatched filesystem

If you set TF_PLUGIN_CACHE_DIR to speed up shared CI runs but the cache directory is on a read-only volume, a tmpfs that gets wiped, or a filesystem that does not preserve executable bits (some SMB mounts), init can succeed once and fail on the second run with “could not query provider packages.” Move the cache to a local writable POSIX-compliant filesystem, or unset the variable to fall back to per-project caching.


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).

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles