Error: Backend configuration changed
Fix Terraform "Backend configuration changed": run terraform init -migrate-state to move state, or init -reconfigure to discard the old setup. Safe CI defaults.
Error: Backend configuration changed
Incident Overview
TerraformTerraform
Fix Terraform "Backend configuration changed": run terraform init -migrate-state to move state, or init -reconfigure to discard the old setup. Safe CI defaults.
medium fix·5 min read
By Vishvesh Patel·DevOps Engineer·Updated 21 September 2026
Error: Backend configuration changed A change in the backend configuration has been detected, which may require migrating existing state. Error: Backend initialization required, please run "terraform init" Error: Initialization required. Please see the error message above.
Do this first3 steps
Run these in order. Each one tells you what its output means before you change anything.
• Compare what is recorded against what the configuration now says
.terraform/terraform.tfstate records the backend Terraform last initialised with. Diffing it against your backend block shows exactly which key changed, which decides whether you need migrate-state or reconfigure.
• If the state should move to the new location, migrate it
This copies the existing state into the new backend and prompts for confirmation. Use it when you are genuinely relocating state, such as moving from local to S3 or changing the key.
• If the state is already where it should be, just reinitialise
This discards the recorded backend and initialises afresh without copying anything. Use it when only credentials or a role changed, or when the new backend already holds the correct state.
Terraform records which backend it last initialised with in .terraform/terraform.tfstate. When the backend block differs, it stops and asks, because the two possible intentions have very different consequences.
Migrating copies the existing state to the new location. Reconfiguring forgets the old backend and starts using the new one as-is.
Pick the wrong one and you either duplicate state or lose track of it.
python3 -c "import json;d=json.load(open('.terraform/terraform.tfstate'));print(json.dumps(d.get('backend',{}).get('config',{}),indent=2))" 2>/dev/nullSee what changed
Compare against your backend block. Any difference triggers this, including ones that do not change where state lives:
python3 -c "import json;d=json.load(open('.terraform/terraform.tfstate'));print(json.dumps(d.get('backend',{}).get('config',{}),indent=2))"Migrating
Read that prompt properly. Answering no gives you an empty state while your infrastructure still exists, and the next apply tries to create everything again.
Back up first, always:
Afterwards, verify:
A plan proposing to create everything means the migration did not carry the state. Restore the backup and try again:
terraform init -migrate-state
Reconfiguring
No copying, no prompt. It discards the recorded backend and initialises the new one.
Wrong when the state has not been copied yet, because you end up pointing at an empty backend with real infrastructure behind it.
terraform init -reconfigure
The safe default in CI
CI runners start clean, so there is no .terraform directory and nothing to migrate. -reconfigure makes the behaviour deterministic and stops a cached workspace from producing a surprise prompt. -lockfile=readonly fails the build if the provider lock file would need to change.
Never use -migrate-state in automation. It is interactive by nature, and the one time it does something unexpected you want a human present.
terraform init -reconfigure -lockfile=readonly
Partial configuration
Hardcoding a bucket name means a different file per environment. Leave the backend block empty and supply values at init:
Or with a file per environment:
Note that backend blocks cannot use variables or expressions. They are evaluated before anything else, so key = "${var.env}/terraform.tfstate" is rejected. Partial configuration exists precisely because of that limitation.
terraform {
backend "s3" {}
}Switching environments in one directory
The -reconfigure is essential here. Without it Terraform offers to migrate production state into the staging backend, and a hurried yes merges two environments.
Workspaces avoid the whole issue for environments that share configuration:
They share one backend with separate state paths, so there is no re-init between environments.
terraform init -reconfigure -backend-config=backends/staging.hcl terraform plan
A checklist
Frequently Asked Questions
What is the difference between -migrate-state and -reconfigure?
-migrate-state copies the existing state from the old backend into the new one and prompts you to confirm. -reconfigure discards Terraform's record of the previous backend and initialises the new one without copying anything. Use migrate when state genuinely needs to move, such as going from local to S3 or changing the key. Use reconfigure when the state is already in the right place and only something like credentials or a role changed.
Why does Terraform ask about this when I only changed the IAM role?
Because it compares the entire backend configuration against what it recorded at the last init, and any difference triggers the check. It has no way to know that role_arn affects how it authenticates rather than where state lives. This is the clearest case for -reconfigure: the state has not moved, so there is nothing to migrate and copying would be wrong.
What happens if I answer "no" to the migration prompt?
Terraform initialises the new backend with an empty state while your real infrastructure carries on existing. The next plan then proposes creating everything from scratch, and applying it either fails on resources that already exist or creates duplicates. Always run terraform state pull > backup.tfstate before a migration, and after it verify with terraform state list and a plan that shows no changes.
Why can I not use variables in a backend block?
Because the backend is initialised before Terraform evaluates variables, locals or anything else in the configuration, so there is nothing available to interpolate. That is why partial configuration exists: leave the block empty and supply the values at init time with -backend-config flags or a .hcl file per environment. It keeps a single set of Terraform files working across environments without hardcoding a bucket and key.
Should I use -reconfigure in CI?
Yes, always, and never -migrate-state. CI runners start from a clean checkout with no .terraform directory, so there is no previous backend to migrate from and nothing to copy. -reconfigure makes the behaviour deterministic even if a cached workspace is reused. -migrate-state is interactive by design and belongs in a session where a person can read the prompt and decide, which is exactly what a pipeline cannot do.
Reference and practice
Learn the underlying concept
Other Terraform errors
Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.
Get notified about new tutorials and features.
• Roadmaps
• Interview Prep
• Certifications
• Company
© 2026 DevOpsLesson. All rights reserved.
Need to practice this scenario?
Simulate this error condition and practice recovery commands safely in our in-browser terminal.