Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Terraform By James Joyner IV · · 8 min read

Terraform Error: 'refresh-only plan cannot be applied' When Applying a Saved Plan

Quick answer

Fix Terraform's 'plan was created with the -refresh-only option and cannot be applied' error: understand refresh-only mode, apply state changes correctly, and regenerate a normal plan.

  • #terraform
  • #iac
  • #troubleshooting
  • #errors
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

Exact Error Message


│ Error: Failed to load "tfplan": plan was created with the -refresh-only option
│ and so cannot be applied.

│ A refresh-only plan can only update the Terraform state to match the real
│ infrastructure; it cannot make changes to remote objects.

You may hit this after running:

terraform plan -refresh-only -out=tfplan
terraform apply tfplan

What It Means

terraform plan -refresh-only produces a plan that only reconciles Terraform’s state with the real world — it detects drift and updates the recorded attributes, but it deliberately proposes no changes to your infrastructure. Terraform marks the saved plan file as refresh-only.

terraform apply <planfile> is meant to execute a set of proposed resource changes. When you hand it a refresh-only plan, Terraform refuses: there are no infrastructure changes to make, only a state update, and the apply-a-saved-plan path is not the mechanism for that. The fix depends on what you actually intended — to record drift into state, or to make real changes.

Common Causes

  • You saved a plan with -refresh-only -out=... and then tried terraform apply <planfile>, expecting it to update state.
  • A CI pipeline uses a generic “plan then apply the saved file” flow, and a refresh-only step was slotted into it.
  • Confusion between -refresh-only (state reconciliation) and a normal plan (infrastructure changes).
  • An attempt to “accept drift” using the saved-plan workflow instead of the interactive refresh-only apply.

Diagnostic Commands

Confirm how the saved plan was created by inspecting it (a refresh-only plan shows no resource actions):

terraform show tfplan

Check for drift without saving anything, to decide what you actually want:

terraform plan -refresh-only

Review the current state and what Terraform believes exists:

terraform state list
terraform show

Step-by-Step Resolution

Pick the path that matches your intent.

  1. If you wanted to record drift into state (accept that the real infrastructure changed and update Terraform’s record), do not use a saved plan file. Run refresh-only apply directly and approve it:
terraform apply -refresh-only

Terraform prints the state-only changes and prompts for yes. This updates state without touching infrastructure.

  1. To do the same non-interactively in CI, auto-approve:
terraform apply -refresh-only -auto-approve
  1. If you actually wanted to change infrastructure, generate a normal plan (without -refresh-only) and apply that:
terraform plan -out=tfplan
terraform apply tfplan
  1. If drift and real changes are both present, first reconcile state, then plan the real changes cleanly:
terraform apply -refresh-only -auto-approve
terraform plan -out=tfplan
terraform apply tfplan
  1. Verify the outcome. After a refresh-only apply, a follow-up plan should report the state now matches reality (or show only the genuine changes you intend):
terraform plan
No changes. Your infrastructure matches the configuration.

If your pipeline blends drift detection and change application into one step, the Terraform workflow prompts in the prompt library can help you split refresh-only drift checks from apply stages so this error stops recurring.

Prevention

  • Keep drift detection and change application as separate pipeline stages; never feed a refresh-only plan into an apply-saved-plan step.
  • Remember the rule: -refresh-only updates state only; a normal plan updates infrastructure.
  • For accepting drift, use terraform apply -refresh-only interactively (or -auto-approve in automation), not a saved plan file.
  • Name saved plan files by intent (for example drift-check.plan vs apply.plan) so they are not mixed up.
  • Run scheduled -refresh-only plans to surface drift early, and act on it before it compounds.
  • Review terraform show <planfile> in CI before applying so a zero-change plan is caught.
  • Saved plan is stale — the state changed after the plan was created, a different saved-plan problem.
  • Error: Cannot apply incomplete plan — the plan file is corrupt or truncated.
  • Note: Objects have changed outside of Terraform — drift detected during a normal plan, which refresh-only addresses.
  • No changes. Your infrastructure matches the configuration. — not an error; the expected result after reconciling drift.

Frequently Asked Questions

What is the point of -refresh-only if it cannot be applied as a saved plan? It exists to reconcile state with reality without proposing infrastructure changes; you apply it with terraform apply -refresh-only, not by passing the saved file to apply.

How do I accept detected drift into state? Run terraform apply -refresh-only and approve it, or -auto-approve in CI; this updates the recorded attributes to match the real objects.

Why does saving the plan then applying fail specifically here? The saved-plan apply path executes proposed resource actions, and a refresh-only plan contains none, so Terraform blocks it to avoid a confusing no-op.

Can I combine drift acceptance and real changes in one command? No — reconcile with terraform apply -refresh-only first, then generate and apply a normal plan for the actual changes. For more workflow fixes, see the Terraform guides.

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.