The Error
You run terraform plan or terraform apply and get stopped cold:
Error: Inconsistent dependency lock file
The following dependency selections recorded in the lock file are inconsistent with the current configuration:
- provider registry.terraform.io/hashicorp/aws: locked version selection 4.67.0 doesn't match the
constraint "~> 5.0" recorded in the configuration
To update the locked dependency selections to match a changed configuration, run:
terraform init -upgrade
Nine times out of ten, the culprit is simple: someone edited required_providers in versions.tf โ bumped a version constraint, added a provider, anything โ and never ran terraform init afterward.
Root Cause
Terraform maintains a .terraform.lock.hcl file. Think of it as a receipt: exact provider versions plus cryptographic checksums, frozen at the time you last ran terraform init.
The moment your .tf files declare a constraint that contradicts those frozen pins, Terraform halts. It won't silently pick a different version. That's intentional โ silent version drift is how prod breaks in ways that are painful to trace.
Common triggers:
- Updated a version constraint in
required_providers(e.g.,~> 4.0โ~> 5.0) - Added a new provider block that has no entry in the lock file yet
- Pulled from git where a teammate changed provider constraints or the lock file itself
- Deleted
.terraform/cache but kept the stale lock file - Running on a different OS โ CI on Linux/amd64 while dev is on macOS/arm64 โ where the lock file only has checksums for one platform
Fix
Option 1: Let Terraform upgrade the lock file (most common fix)
Terraform literally tells you what to run in the error output:
terraform init -upgrade
This re-resolves every provider against your current constraints and rewrites .terraform.lock.hcl from scratch. Commit it immediately.
git add .terraform.lock.hcl
git commit -m "chore: update terraform provider lock file"
Option 2: Add a new provider without touching existing pins
Just added a brand-new provider and don't want to risk bumping anything else? Skip the -upgrade flag:
terraform init
Plain terraform init only downloads providers that are missing from the lock file. Versions already pinned stay pinned. Safer choice when your change is purely additive.
Option 3: Fix a cross-platform checksum mismatch
Your CI pipeline (Linux/amd64) fails, but your MacBook (macOS/arm64) runs fine. The lock file has checksums for your laptop's architecture but not the CI runner's. Fix it without changing any versions:
terraform providers lock \
-platform=linux_amd64 \
-platform=darwin_arm64 \
-platform=darwin_amd64
Commit the result. Now the lock file carries checksums for every platform your team touches, and CI stops complaining.
Option 4: Pin an exact version to stop drift
Say -upgrade pulled in aws provider 5.89.0 and you're not ready for that. Lock it down explicitly in versions.tf:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "= 5.31.0" # exact pin, no drift
}
}
}
Run terraform init -upgrade again. Terraform will now lock to 5.31.0 regardless of what your teammates do with -upgrade on their machines.
Option 5: Delete the lock file and start fresh (last resort)
Reserve this for a genuinely corrupted lock file or a brand-new environment you're bootstrapping from zero:
rm .terraform.lock.hcl
terraform init
Terraform regenerates everything from scratch. Review the new pins before you commit โ you want to know what versions you're now running.
Verify the Fix
Two quick checks after any of the fixes above:
# Should complete without errors
terraform init
# Should show a plan without lock file errors
terraform plan
Confirm the lock file actually has the provider version you expect:
grep -A3 'provider "registry.terraform.io/hashicorp/aws"' .terraform.lock.hcl
You should see something like:
provider "registry.terraform.io/hashicorp/aws" {
version = "5.31.0"
constraints = "~> 5.0"
hashes = [
Prevention
- Commit
.terraform.lock.hclโ always. Treat it exactly likepackage-lock.json. It is not optional, it is not noise, and it does not belong in.gitignore. - Run
terraform initafter every pull that touches.tffiles. Make it a habit, especially afterversions.tfchanges. - Add platform checksums before your first CI commit. Run
terraform providers lock -platform=linux_amd64locally so the CI runner never hits a mismatch on day one. - Use
= x.y.zexact pins in shared or production environments. Range constraints like~> 5.0are convenient in development but can bite you when a teammate's-upgradesilently pulls a newer minor version. - If you ever need to validate version constraint syntax in your
versions.tfYAML blocks, the YAML โ JSON Converter on ToolCraft is handy โ runs entirely in-browser, no upload needed.
Quick Reference
# Added a new provider โ just init
terraform init
# Updated a version constraint โ upgrade lock file
terraform init -upgrade
# Cross-platform CI mismatch โ add platform checksums
terraform providers lock -platform=linux_amd64 -platform=darwin_arm64
# Nuclear option (corrupted lock file)
rm .terraform.lock.hcl && terraform init
# Always commit the lock file after changes
git add .terraform.lock.hcl && git commit -m "chore: update lock file"

