hashicorp/terraform · error

error: using a saved cloud plan when executing Terraform…

Error message

error: using a saved cloud plan when executing Terraform locally is not supported

What it means

Returned by Local.localRun when op.PlanFile.IsCloud() is true. A cloud (Terraform Cloud / HCP) plan file contains server-side references that must be redeemed by the cloud backend, not the local backend, so executing it locally is structurally unsupported rather than merely failing.

Solutions

  1. Apply cloud plans from within the cloud run (use the TFC/TFE UI or API), not via local `terraform apply <file>`.
  2. If you need a locally-applied plan, generate it locally with `terraform plan -out=tfplan` against the local (or remote-state) backend, then `terraform apply tfplan`.
  3. Switch the active backend to the cloud backend (`backend "cloud"`) if your intent is to apply in the cloud execution environment.
  4. Do not rename or copy a cloud plan file to fool IsCloud(); the format is incompatible and will fail later even if this check is bypassed.

Example fix

# before: applying a cloud-downloaded plan locally
terraform apply tfplan-from-tfc   # -> error: using a saved cloud plan ... not supported
# after: apply it in TFC, or generate+apply locally
terraform plan -out=tfplan
terraform apply tfplan
Defensive patterns

Strategy: validation

Validate before calling

// Detect cloud plans up front and steer users to the right workflow.
if op.PlanFile != nil && op.PlanFile.IsCloud() {
    return fmt.Errorf("a saved cloud plan cannot be applied by the local backend; apply it in TFC/TFE or generate a local plan with 'terraform plan -out'")
}

Type guard

// Distinguish plan file kinds before dispatching.
func isLocalPlan(pf backendrun.PlanFile) bool {
    if pf == nil { return false }
    _, ok := pf.Local(); return ok
}

Try / catch

lr, _, diags := b.LocalRun(ctx, op)
if diags.HasErrors() && strings.Contains(diags.Err().Error(), "saved cloud plan") {
    // tell the user to switch to the cloud backend or generate a local plan
}

Prevention

When it happens

Trigger: The user runs `terraform apply <file>` (or any local operation) where <file> is a plan downloaded from a Terraform Cloud run, while the active backend is the local (or any non-cloud) backend. op.PlanFile.IsCloud() returns true and localRun short-circuits.

Common situations: Downloading a plan artifact from a TFC/TFE run and trying to apply it from a developer laptop; mixing a cloud-produced plan with a local apply workflow; CI that fetches a cloud plan but runs the apply step with the default local backend.

Related errors


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

Appendix: source

Thrown at internal/backend/local/backend_local.go:91

	}

	ret := &backendrun.LocalRun{
		PolicyClient: op.PolicyClient,
	}

	// Initialize our context options
	var coreOpts terraform.ContextOpts
	if v := b.ContextOpts; v != nil {
		coreOpts = *v
	}
	coreOpts.UIInput = op.UIIn
	coreOpts.Hooks = op.Hooks
	coreOpts.TracingContext = ctx

	var ctxDiags tfdiags.Diagnostics
	var configSnap *configload.Snapshot
	if op.PlanFile.IsCloud() {
		diags = diags.Append(fmt.Errorf("error: using a saved cloud plan when executing Terraform locally is not supported"))
		return ret, nil, nil, diags
	}

	if lp, ok := op.PlanFile.Local(); ok {
		var stateMeta *statemgr.SnapshotMeta
		// If the statemgr implements our optional PersistentMeta interface then we'll
		// additionally verify that the state snapshot in the plan file has
		// consistent metadata, as an additional safety check.
		if sm, ok := s.(statemgr.PersistentMeta); ok {
			m := sm.StateSnapshotMeta()
			stateMeta = &m
		}
		log.Printf("[TRACE] backend/local: populating backendrun.LocalRun from plan file")
		ret, configSnap, ctxDiags = b.localRunForPlanFile(op, lp, ret, &coreOpts, stateMeta)
		if ctxDiags.HasErrors() {
			diags = diags.Append(ctxDiags)
			return ret, nil, nil, diags
		}

View on GitHub (pinned to d32a084675)