Terraform Error Guide: 'Inconsistent dependency lock file' on init/plan
Fix Terraform's 'Inconsistent dependency lock file' error: reconcile .terraform.lock.hcl hashes, missing platforms, version bumps, and CI -lockfile=readonly runs.
- #terraform
- #troubleshooting
- #errors
- #providers
Overview
Terraform records the exact provider versions and checksums it selected in .terraform.lock.hcl. On every init and plan it re-checks that the providers required by your configuration still match what the lock file pins. When the configuration asks for a version the lock file does not allow, or the lock file is missing a hash for your platform, Terraform refuses to proceed so it never silently installs an unverified provider.
You will see this on terraform plan (or apply in automation):
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
5.31.0 doesn't match the updated version constraints "~> 5.40"
To update the locked dependency selections to match a changed configuration,
run:
terraform init -upgrade
It commonly fires after someone bumps a required_providers version, after a terraform init on a new OS/arch whose hash was never recorded, or in CI where -lockfile=readonly forbids the lock file from being updated.
Symptoms
init/planfail withInconsistent dependency lock file.- A
locked version selection ... doesn't match the updated version constraintsmessage. - CI fails but local works (different OS/arch, or CI uses
-lockfile=readonly). - A provider version was bumped in
versions.tfbut the lock file was not regenerated.
terraform plan
Error: Inconsistent dependency lock file
- provider registry.terraform.io/hashicorp/random: locked version selection
3.5.1 doesn't match the updated version constraints ">= 3.6.0"
Common Root Causes
1. A version constraint was bumped but the lock not updated
Someone edited required_providers to a newer range and committed it without running terraform init -upgrade, so the lock still pins the old version.
grep -A4 required_providers versions.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.40"
}
}
}
# .terraform.lock.hcl still has:
version = "5.31.0"
constraints = "~> 5.31"
The lock’s 5.31.0 is outside the new ~> 5.40 constraint.
2. Missing hashes for the current platform
The lock was generated on macOS/arm64 only, and CI runs on linux/amd64 whose hash was never recorded.
grep -A6 'hashicorp/aws' .terraform.lock.hcl
hashes = [
"h1:abc...=",
"zh:111...",
]
If none of the h1:/zh: hashes cover linux/amd64, init on Linux fails to verify.
3. CI runs with -lockfile=readonly
The pipeline pins the lock as read-only so it cannot self-heal a drifted lock, surfacing the inconsistency as a hard error.
grep -r 'lockfile' .github/ Makefile 2>/dev/null
terraform init -input=false -lockfile=readonly
Readonly is correct for reproducibility — but it means the lock must be committed already up to date.
4. Merge conflict left the lock half-resolved
A Git merge of two branches that each bumped a provider can leave the lock with a stale version or duplicate blocks.
git diff --check .terraform.lock.hcl
grep -c 'provider "' .terraform.lock.hcl
<<<<<<< HEAD
Conflict markers or a partially merged block make the lock inconsistent.
5. A provider source moved namespaces
Switching from a community to an official provider (source change) leaves the old provider’s lock entry that no longer matches the configuration.
grep 'source' versions.tf
grep 'provider "registry' .terraform.lock.hcl
source = "hashicorp/aws"
provider "registry.terraform.io/-/aws"
The lock references a different source than required_providers.
6. Lock file not committed (only .gitignore’d)
If .terraform.lock.hcl is gitignored, every environment regenerates its own and CI sees an “updated” constraint it cannot match under readonly.
git check-ignore .terraform.lock.hcl
.terraform.lock.hcl
A gitignored lock should almost always be removed from ignore and committed.
Diagnostic Workflow
Step 1: Read which provider/version is inconsistent
terraform plan 2>&1 | grep -A3 "doesn't match"
Note the provider source and whether it is a version mismatch or a missing-hash case.
Step 2: Compare constraint vs. lock
grep -A4 required_providers versions.tf
grep -E 'version|constraints' .terraform.lock.hcl
Confirm the lock’s version falls outside the configuration’s constraint.
Step 3: Check for merge conflicts or wrong source
git diff --check .terraform.lock.hcl
grep 'provider "registry' .terraform.lock.hcl
Resolve any conflict markers and verify the source namespace matches required_providers.
Step 4: Regenerate the lock locally with all platforms
terraform init -upgrade
terraform providers lock \
-platform=linux_amd64 -platform=darwin_arm64 -platform=windows_amd64
providers lock records hashes for every platform your team and CI use, fixing missing-hash failures.
Step 5: Commit the lock and re-run CI in readonly
git add .terraform.lock.hcl
terraform init -input=false -lockfile=readonly && terraform plan
A clean readonly init confirms the lock now matches the configuration everywhere.
Example Root Cause Analysis
A pipeline that worked yesterday now fails at init with:
Error: Inconsistent dependency lock file
- provider registry.terraform.io/hashicorp/aws: locked version selection
5.31.0 doesn't match the updated version constraints "~> 5.40"
Checking the recent change, a teammate bumped the AWS provider:
git log -1 --stat versions.tf
versions.tf | 2 +-
- version = "~> 5.31"
+ version = "~> 5.40"
The constraint moved to ~> 5.40 but .terraform.lock.hcl was not committed in that change, so it still pins 5.31.0. CI runs -lockfile=readonly, so it cannot update the lock itself and errors.
Fix: regenerate the lock for all platforms and commit it.
terraform init -upgrade
terraform providers lock -platform=linux_amd64 -platform=darwin_arm64
git add .terraform.lock.hcl versions.tf
After committing the updated lock, the readonly CI init succeeds and plan runs clean.
Prevention Best Practices
- Always commit
.terraform.lock.hcland never gitignore it — it is the reproducibility guarantee for providers. - Whenever you bump a
required_providersversion, runterraform init -upgradein the same change and commit the updated lock. - Record hashes for every platform your team and CI use with
terraform providers lock -platform=...so Linux CI never fails on a macOS-only lock. - Keep CI on
-lockfile=readonlyso drift is caught in review, not silently installed. - Resolve lock merge conflicts by regenerating the lock rather than hand-editing hashes.
- For quick triage, the free incident assistant can read the mismatch message and point you at the version vs. constraint gap. See more in the Terraform guides.
Quick Command Reference
# Which provider is inconsistent?
terraform plan 2>&1 | grep -A3 "doesn't match"
# Compare constraint vs. locked version
grep -A4 required_providers versions.tf
grep -E 'version|constraints' .terraform.lock.hcl
# Check for merge conflicts / wrong source
git diff --check .terraform.lock.hcl
# Regenerate the lock and record all platforms
terraform init -upgrade
terraform providers lock \
-platform=linux_amd64 -platform=darwin_arm64 -platform=windows_amd64
# Verify under readonly (as CI does)
terraform init -input=false -lockfile=readonly && terraform plan
Conclusion
Inconsistent dependency lock file means .terraform.lock.hcl no longer agrees with the providers your configuration requires. The usual root causes:
- A
required_providersversion bump without regenerating the lock. - Missing provider hashes for the current OS/arch (often Linux CI vs. macOS dev).
- CI runs
-lockfile=readonlyagainst a drifted, uncommitted lock. - A merge conflict left the lock half-resolved.
- A provider
sourcenamespace change orphaned the lock entry. - The lock file is gitignored and regenerated differently per environment.
Run terraform init -upgrade, record every platform with terraform providers lock, and commit the result — then a readonly CI init stays green.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.