agent's terraform plan looked clean but apply failed on a constraint the plan never evaluated
Fixes Terraform runs where plan looks clean but apply fails on a constraint the plan never evaluated. It shows how to read the apply error, classify it as ordering, eventual consistency, or a real constraint, and fix each one. Use when terraform apply fails after a clean plan.
TL;DR: Plan is a local graph evaluation - it cannot see server-side constraints, eventual consistency, or quota. Read the apply error literally: if it is ordering, add the missing dependency or split the apply; if it is eventual consistency, wait and retry; if it is a real constraint, fix the config. Then re-run apply until the plan is empty.
agent's terraform plan looked clean but apply failed on a constraint the plan never evaluated- Read the full apply error, not just the summary line. Identify the resource, the provider, and the exact constraint named.
Expected: you can state which resource failed and what rule it violated, in the provider's own words.
- Classify the failure. Ordering: resource B needed resource A to exist first (classic sign: not found errors on something the same apply creates). Eventual consistency: the object was just created but is not visible yet (classic sign: IAM, DNS, or new service-linked roles). Real constraint: a quota, a policy, or a validation rule your config actually violates.
Expected: the failure falls into exactly one of the three buckets.
- Fix by bucket. Ordering: add an explicit depends_on or split into two applies. Eventual consistency: wait for propagation and re-run, or add a retry loop around the apply. Real constraint: change the config to satisfy the rule (raise the quota, fix the value, satisfy the policy).
Expected: you can explain why your fix addresses the bucket, not just the symptom.
- Re-run terraform apply and confirm it converges.
Expected: apply succeeds and a follow-up terraform plan reports no changes.
- Harden the config: keep the depends_on you added, and note any propagation waits in the module docs so the next person does not rediscover them.
Expected: a second clean apply from scratch reproduces the success.
Use this when
- terraform plan succeeds but terraform apply fails
- The apply error names a constraint, a missing dependency, or a not-yet-visible resource
- You hit eventual consistency right after creating IAM roles, DNS records, or new service features
- A provider validates something at apply time that plan could not know
Not for this skill when
- Plan itself fails - that is a config or state problem, fix it before thinking about apply
- The error is a state lock or backend issue - that is operational, not a plan/apply divergence
- Apply fails on a resource tainted in a previous run - untaint or replace it explicitly
- You are using plan files across long gaps - re-plan, because the world moved since the plan was made
Variant phrasings
- terraform plan clean but apply fails
- terraform apply error constraint not in plan
- plan did not catch apply failure
- terraform eventual consistency apply failed after plan
Why it happens
Plan evaluates your configuration against the state file and the provider's schema, all locally. It cannot call every validation the real API performs, it cannot know that a resource created two seconds ago is not yet visible in another region's read path, and it cannot see quotas or organization policies that live outside the state. Apply is the first moment your config meets the real world, so the real world gets the first vote.
Edge cases
- Splitting applies to fix ordering can leave half-applied state if the second apply is forgotten. Always finish with a confirming empty plan.
- Eventual-consistency retries need a bounded wait. If it has not converged after the provider's documented propagation window, reclassify as a real constraint.
- Some providers validate more at plan time with newer versions. If this bites often, upgrading the provider can move failures left into plan.
- A plan file saved hours ago can go stale. Re-plan right before apply on fast-moving infrastructure.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_g8UrGp5ToNOhcXUNs6asUQ
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.