Troubleshooting — The Builder's Problem Desk
Every Terraform user eventually meets a scary error. This is the Problem Desk: what the message means, why it happened, and how to get out. Each problem follows the same Problem → Cause → Fix rhythm you know.
1 · "Error acquiring the state lock"
terraform apply waits, then fails with Error acquiring the state lock.
Cause: Someone else (or a stuck CI job) is running a Terraform command that holds the lock on the remote state. The lock exists to prevent two people from building over each other.
Fix:
# Wait a moment and retry — the other run may finish quickly
terraform plan
If the lock is stuck (a crashed process left it behind), force-release it — but only after confirming no one is genuinely running:
terraform force-unlock <LOCK_ID>
The lock ID is printed in the error message.
A lock error is Terraform protecting you. Always confirm a run isn't actually in progress before force-unlocking.
2 · The plan unexpectedly says "will destroy"
You run terraform plan and something you care about is listed under will destroy — or worse, a resource will be replaced.
Cause (usually one of):
- The resource was removed from the configuration (deleted the block, or a
for_eachkey disappeared). - The resource was renamed in config — Terraform treats it as delete-old + create-new.
- An argument that can't be changed in place forces replacement.
Fix: Read the plan carefully before applying.
terraform plan
- Intended removal? Fine — let it destroy.
- Renamed a resource? Use
terraform state mvto rename it in state without touching the live resource, then apply.
terraform state mv aws_s3_bucket.old_name aws_s3_bucket.new_name
If a plan says a database will be replaced, stop and check — that usually means data loss. Look for "forces replacement" in the plan output.
3 · Drift — resources changed outside Terraform
A plan shows changes to resources you didn't edit — because someone changed them in the AWS console.
Cause: Drift. Reality no longer matches state.
Fix: Refresh state to match reality, then review the true diff:
terraform apply -refresh-only
terraform plan
Now plan shows only the difference between blueprint and reality. Either re-apply to restore the blueprint, or update the blueprint to accept the change.
4 · Credentials errors — "no valid credential sources"
terraform plan fails with no valid credential sources found or an access-denied error.
Cause: The AWS provider can't find credentials. Terraform looks in order: environment variables, shared config (~/.aws/credentials), then IAM roles.
Fix:
# Make sure the keys are actually exported
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY
# Or point at a named profile
export AWS_PROFILE=my-profile
Each terminal session needs its own exports — close the terminal and the keys are gone. This is why teams use shared config files or IAM roles instead.
5 · Backend / state file errors
Errors like initialization required, backend configuration changed, or state file not found.
Cause: Your working directory isn't initialized for this backend, or the backend block changed.
Fix:
terraform init
When you add or change a backend block, init reconfigures and offers to migrate the existing state to the new location:
terraform init -migrate-state
6 · "Inconsistent dependency lock file"
terraform init refuses with the dependency lock file is inconsistent.
Cause: terraform.lock.hcl pins provider versions, but the current config (or your checksums) don't match — usually after upgrading a provider or pulling a teammate's change.
Fix:
terraform init -upgrade
This refreshes the lock file to match the current configuration. Commit the updated lock file so the team stays in sync.
7 · "Resource already exists" — or resources created outside Terraform
Apply fails because the resource already exists — it was created manually, or is in another Terraform state.
Cause: Terraform doesn't know about it. The register has no entry for that bucket/instance.
Fix: Import it into state, then Terraform will manage it:
terraform import aws_s3_bucket.archive campus-library-archive
Then run plan — it will show what differs from your blueprint.
8 · Validation errors on validate or plan
An HCL error — an unknown argument, a missing closing brace, a wrong type.
Cause: A syntax or type mistake in the blueprint.
Fix:
terraform fmt # auto-fix spacing/indentation
terraform validate # fresh error report
validate points at the exact block and line. Most validation errors are a missing brace or a list passed where a string was expected.
Still stuck?
The Problem Desk always starts with the same two steps:
terraform plan # what does Terraform think reality should be?
terraform state list # what does the register say exists?
If you can answer "what's in state?" and "what does the plan want to do?", you can usually spot the mismatch yourself. And if a term confuses you, the Glossary is one click away.