Skip to main content
DevOps Insightsguides & answers

Terraform · troubleshooting

Error: Backend configuration changed

The backend settings in your configuration no longer match what this working directory was set up with, so Terraform wants init again. Use -migrate-state to move existing state to the new settings; -reconfigure ignores it, so the next plan would recreate everything.

Reproduced on Terraform 1.14.0, . Where the text says “reproduced”, the behaviour was run on that version, not taken from documentation.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 9 sections

Before you start

  • The error output, and the backend block plus any -backend-config values your scripts pass.
  • Access to the old and the new backend, and a backup of the state before migrating.

Run this first

step 1 of 2
terraform plan 2>&1 | grep -A1 'Reason:'

Look for Backend configuration block has changed, or Initial configuration of the requested backend

The reason line tells you whether the configuration changed or was never initialised.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

What do you need?

Cause space

3 of 3 still possible

  • You changed where state lives and want to keep itCommon
  • CI or a teammate initialised with different -backend-config valuesCommon
  • The directory was never initialisedCommon

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    terraform plan 2>&1 | grep -A1 'Reason:'

    The reason line tells you whether the configuration changed or was never initialised.

    Look for Backend configuration block has changed, or Initial configuration of the requested backend

  2. Step 2

    cat .terraform/terraform.tfstate 2>/dev/null | head -20

    This file records the backend settings this directory was last initialised with (not your infrastructure state).

    Look for The old bucket, key or path, to compare with the configuration

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

You changed where state lives and want to keep it

Common

A new bucket, key, region or backend type, or switching from local state to a remote backend. The existing state must come along.

Confirm

git diff HEAD~1 -- '*.tf' | grep -A6 'backend'

A changed bucket, key, path, region or backend type

Fix

  • Back up first: terraform state pull > backup.tfstate (with the old settings still initialised), or copy the old state file.
  • Then migrate: terraform init -migrate-state, answer yes (or add -force-copy in a script).
  • Run terraform plan and expect No changes before doing anything else.
terraform init -migrate-state

Copies state to the new backend settings; add -force-copy to skip the prompt in automation. Reproduced on Terraform 1.14.0.

CI or a teammate initialised with different -backend-config values

Common

The same directory is used for several environments with different -backend-config files or keys, and the .terraform directory still remembers the last one.

Confirm

grep -rn -- '-backend-config' .github/ Makefile scripts/ 2>/dev/null
ls .terraform/terraform.tfstate

Different backend values per environment, and a cached .terraform from another run

Fix

  • Point at the environment you mean without moving state: terraform init -reconfigure -backend-config=ENV.hcl. Here -reconfigure is right, because each environment's state already lives in its own location.
  • In CI, start from a clean working directory (no cached .terraform), so every run initialises from scratch.

The directory was never initialised

Common

A fresh clone, a new CI runner or a deleted .terraform directory. Nothing changed; init simply has not run.

Confirm

ls -d .terraform 2>/dev/null || echo 'not initialised'

not initialised

Fix

  • Run terraform init (with the same -backend-config your environment uses).

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

Terraform keeps its record of what it built (state) in a backend, such as an S3 bucket or a local file. When you change where that is, by editing the backend block or passing different -backend-config values, Terraform stops and asks you to run init again, because it must decide whether to bring the old state along. Choosing wrong here is how teams end up with Terraform trying to recreate infrastructure that already exists.

Words used on this page

Backend
Where Terraform stores state and how it locks it: local, s3, gcs, azurerm, remote and others.
-migrate-state
init option that copies existing state from the old backend settings to the new ones.
-reconfigure
init option that adopts the new backend settings and ignores the old ones, without copying state.
-backend-config
Values for the backend block passed at init time (a file or key=value), common in CI to pick a bucket or key per environment.
What is actually happening

Reproduced on Terraform 1.14.0 with the local backend: after changing its path, terraform plan stopped with Backend initialization required: please run "terraform init" and Reason: Backend configuration block has changed. A non-interactive terraform init stopped with Error: Backend configuration changed and told us to choose terraform init -migrate-state or terraform init -reconfigure.

The two choices are not interchangeable. In the reproduction, init -migrate-state (with -force-copy, as a script would run it) copied the state, and the next plan said No changes. init -reconfigure did not copy it, and the next plan proposed 1 to add: the existing resource looked new. Against real infrastructure that means duplicate resources or apply errors.

Run interactively, init -migrate-state asks Do you want to copy existing state to the new backend? and accepts yes or no; -force-copy answers yes for automation.

A directory that was never initialised (a fresh clone, a new CI runner) fails earlier with Backend initialization required, please run "terraform init" and Reason: Initial configuration of the requested backend. That one only needs a plain terraform init.

How to tell this is your problem
WhereWhat you see
terraform plan or applyError: Backend initialization required: please run "terraform init" … Reason: Backend configuration block has changed
terraform initError: Backend configuration changed … If you wish to attempt automatic migration of the state, use "terraform init -migrate-state". If you wish to store the current configuration with no changes to the state, use "terraform init -reconfigure".
Fresh checkoutError: Backend initialization required, please run "terraform init" … Reason: Initial configuration of the requested backend

How to know it is actually fixed

  • terraform plan shows No changes (or only the changes you expected) after init.
  • The new backend location holds the state, and the old one is kept until you are sure.

Stopping it happening again

  • Change backend settings in their own pull request, and run init -migrate-state deliberately, with a backup.
  • Keep per-environment backend values in separate files and initialise with -reconfigure -backend-config=FILE in a clean directory.

Security considerations

  • Back up state before migrating: terraform state pull > backup.tfstate. A failed or mistaken migration is far easier to undo with a copy.
  • Never run -reconfigure in an automated pipeline without knowing the new location already has the right state; an apply on empty state will try to create duplicates or fail on names that exist.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it