hashicorp/terraform · critical

Workspace data missing from plan file. Current workspace is

Error message

Workspace data missing from plan file. Current workspace is %q. This is a bug in Terraform and should be reported.

What it means

A panic in `meta_backend.go:351` during `BackendForLocalPlan`/plan application. When deciding which workspace a plan targets, the code switches on `plan.StateStore` vs `plan.Backend`; if BOTH are nil (neither workspace source is present) it panics, naming the current workspace and explicitly calling it 'a bug in Terraform'. A valid plan file always carries exactly one of these.

Source

Thrown at internal/command/meta_backend.go:351

	var diags tfdiags.Diagnostics

	// Check the workspace name in the plan matches the current workspace
	currentWorkspace, err := m.Workspace()
	if err != nil {
		diags = diags.Append(fmt.Errorf("error determining current workspace when initializing a backend from the plan file: %w", err))
		return nil, diags
	}
	var plannedWorkspace string
	var isCloud bool
	switch {
	case plan.StateStore != nil:
		plannedWorkspace = plan.StateStore.Workspace
		isCloud = false
	case plan.Backend != nil:
		plannedWorkspace = plan.Backend.Workspace
		isCloud = plan.Backend.Type == "cloud"
	default:
		panic(fmt.Sprintf("Workspace data missing from plan file. Current workspace is %q. This is a bug in Terraform and should be reported.", currentWorkspace))
	}
	if currentWorkspace != plannedWorkspace {
		return nil, diags.Append(&errWrongWorkspaceForPlan{
			currentWorkspace: currentWorkspace,
			plannedWorkspace: plannedWorkspace,
			isCloud:          isCloud,
		})
	}

	var b backend.Backend
	switch {
	case plan.StateStore != nil:
		settings := plan.StateStore

		// BackendForLocalPlan is used in the context of an apply command using a plan file,
		// so we can read locks directly from the lock file and trust it contains what we need.
		locks, lockDiags := m.lockedDependencies()
		diags = diags.Append(lockDiags)

View on GitHub (pinned to c9def3e214)

Solutions

  1. Regenerate the plan with a fresh `terraform plan -out=tfplan` using the current binary, then apply.
  2. Delete the suspect plan file and re-plan; do not retry the corrupted artifact.
  3. If it recurs on a freshly generated plan, report a Terraform bug with the backend/state_store configuration and terraform version.
  4. Ensure the working directory has the backend/state_store block configured and `terraform init` has completed.

Example fix

null
Defensive patterns

Strategy: validation

Validate before calling

// Go: sanity-check a plan carries backend/state-store workspace data before applying
func ensurePlanHasWorkspace(p *plans.Plan) error {
	if p.Backend == nil && p.StateStore == nil {
		return errors.New("plan file is missing backend/state_store data; regenerate with terraform plan")
	}
	return nil
}

Try / catch

// Go: recover during plan-driven backend init
defer func() {
	if r := recover(); r != nil {
		err = fmt.Errorf("plan file appears corrupt (%v); regenerate it with terraform plan", r)
	}
}()
backend, err := m.BackendForLocalPlan(plan)

Prevention

When it happens

Trigger: Applying a saved plan file (`terraform apply tfplan`) where the serialized plan object has neither a `backend` block nor a `state_store` block. This indicates the plan was produced by a broken/corrupt serialization or a binary with a regression in plan encoding.

Common situations: Corrupted plan file; a plan saved by an experimental or patched Terraform that omitted backend metadata; partial write of a plan artifact (disk full, killed mid-write); version mismatch between plan writer and applier.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/ef160c201e8aa8e4. Report an issue: GitHub.