hashicorp/terraform · error

Migration aborted by user.

Error message

Migration aborted by user.

What it means

Returned in the multi-state-to-multi-state migration when the user is asked to confirm migrating all workspaces and answers in the negative (or `opts.force` is false and `migrate` resolves false). It is an explicit user-initiated abort, not a system failure.

Solutions

  1. Re-run init and answer `yes` to the migration prompt.
  2. Use `-migrate-state=true` to skip the prompt and proceed with migration.
  3. If you genuinely do not want migration, use `-migrate-state=false` and accept that the destination backend starts empty.

Example fix

# before
terraform init   # answered 'no'
# after
terraform init -migrate-state=true
Defensive patterns

Strategy: validation

Validate before calling

# Express migration intent as a CI variable so the prompt never blocks.
MIGRATE=${MIGRATE_STATE:-true}
terraform init -input=false -migrate-state=$MIGRATE

Try / catch

# A user 'no' is a decision, not a failure — surface it distinctly:
if terraform init 2>&1 | tee /tmp/init.log; then :; else
  if grep -q 'Migration aborted by user' /tmp/init.log; then
    echo "Migration declined by operator; investigate intent" >&2; exit 3
  fi
fi

Prevention

When it happens

Trigger: Fires in `backendMigrateState_S_S` after the `backend-migrate-multistate-to-multistate` prompt returns successfully but with a value that is not truthy (e.g. the user types `no` or `n`).

Common situations: A developer re-runs `terraform init` after editing the backend and chooses not to migrate, or an automated harness that auto-answers `no` to all prompts.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/9cc010491156e49a. Report an issue: GitHub.

Appendix: source

Thrown at internal/command/meta_backend_migrate.go:190

	if !migrate {
		var err error
		// Ask the user if they want to migrate their existing remote state
		migrate, err = m.confirm(&terraform.InputOpts{
			Id: "backend-migrate-multistate-to-multistate",
			Query: fmt.Sprintf(
				"Do you want to migrate all workspaces to %s %q?",
				dstWord, opts.DestinationType),
			Description: fmt.Sprintf(
				strings.TrimSpace(inputBackendMigrateMultiToMulti),
				opts.SourceType, srcWord, opts.DestinationType, dstWord),
		})
		if err != nil {
			return fmt.Errorf(
				"Error asking for state migration action: %s", err)
		}
	}
	if !migrate {
		return fmt.Errorf("Migration aborted by user.")
	}

	// Read all the states
	sourceWorkspaces, wDiags := opts.Source.Workspaces()
	if wDiags.HasErrors() {
		return fmt.Errorf(strings.TrimSpace(
			errMigrateLoadStates), opts.SourceType, srcWord, wDiags.Err())
	}
	if wDiags.HasWarnings() {
		log.Printf("[WARN] backendMigrateState_S_S: warning(s) returned when getting workspaces from source backend: %s", wDiags.ErrWithWarnings())
	}

	// Sort the states so they're always copied alphabetically
	sort.Strings(sourceWorkspaces)

	// Go through each and migrate
	for _, name := range sourceWorkspaces {
		// Copy the same names

View on GitHub (pinned to d32a084675)