OpenTofu Error Guide: 'Provider produced inconsistent result after apply' — Diagnose a Buggy Provider
Fix OpenTofu's 'Provider produced inconsistent result after apply' error: understand why plan and post-apply state disagree, isolate provider bugs and eventual-consistency issues, and stabilize your applies.
- #iac
- #infrastructure-as-code
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
OpenTofu enforces a contract between the plan and the apply: whatever a provider promised during plan must match what it reports after apply. When a provider returns an attribute value after apply that differs from what it planned (and the difference was not marked “known after apply”), OpenTofu aborts with a provider-bug error:
Error: Provider produced inconsistent result after apply
When applying changes to aws_instance.web, provider "registry.opentofu.org/hashicorp/aws"
produced an unexpected new value: .private_dns: was cty.StringVal(""), but now
cty.StringVal("ip-10-0-1-42.ec2.internal").
This is a bug in the provider, which should be reported in the provider's own
issue tracker.
The message names the resource, the specific attribute, and the planned value versus the actual value. The wording (“This is a bug in the provider”) is accurate — this is a plan/apply consistency violation that OpenTofu surfaces rather than silently accepting. But “provider bug” often has a practical root cause you can work around: eventual consistency at the cloud API, a resource whose value is genuinely only knowable after creation, a version mismatch, or an interaction with ignore_changes/computed attributes. Critically, when this fires the resource was frequently already created in the cloud — so the run half-succeeded and state may need reconciliation.
Symptoms
tofu applyfails at the end of a resource’s creation/update withProvider produced inconsistent result after apply.- The error names a specific attribute and shows
was <planned>, but now <actual>. - The resource often exists in the cloud despite the failed apply (partial success).
- Re-running
applysometimes succeeds (eventual consistency) and sometimes fails identically (a real provider bug). - May also appear as the sibling error
Provider produced inconsistent final plan.
tofu apply
Error: Provider produced inconsistent result after apply
...produced an unexpected new value: .arn: was known, but now null.
Common Root Causes
1. Cloud API eventual consistency
The provider read an attribute back before the cloud API had fully populated it, so the post-apply value differs from the planned one. Common with attributes computed asynchronously (DNS names, ARNs on some resources, tags propagating).
.private_dns: was cty.StringVal(""), but now cty.StringVal("ip-10-0-1-42...")
2. An outdated or mismatched provider version
An older provider version has a known plan/apply consistency bug that a newer release fixes (or vice-versa — a regression). Version drift between team members or CI and local is a frequent trigger.
tofu version
OpenTofu v1.8.0
+ provider registry.opentofu.org/hashicorp/aws v5.31.0 # known bug; v5.40+ fixes it
3. A genuinely computed attribute the provider mis-declared
The provider failed to mark an attribute as Computed/“known after apply”, so OpenTofu planned a concrete value (often "" or null) that the cloud then overrode. This is the textbook provider bug and needs an upstream fix or an ignore_changes workaround.
4. Interaction with ignore_changes or a bad lifecycle block
An ignore_changes on an attribute that the provider then changes during apply can surface as an inconsistency, because the planned (ignored) value and the applied value diverge.
5. A provider interacting with out-of-band mutation
Something else (an AWS default, an admission controller, a mutating webhook, an autoscaler) modified the resource between plan and the provider’s post-apply read, so the value the provider read back is not what it wrote.
Diagnostic Workflow
Step 1: Read exactly which attribute diverged
The error is precise — capture the resource, attribute, and both values:
tofu apply 2>&1 | grep -A3 'inconsistent result'
When applying changes to aws_instance.web, provider "...aws" produced an
unexpected new value: .private_dns: was cty.StringVal(""), but now ...
Step 2: Check whether the resource was actually created
This error usually leaves the resource created but the apply marked failed. Confirm before re-running:
tofu state list | grep aws_instance.web
tofu state show aws_instance.web
If the resource is in state, a plain re-apply may now converge (eventual consistency). If it is half-tracked, you may need a targeted refresh.
Step 3: Reconcile state, then re-plan
Refresh so state reflects the actual post-apply cloud values, then see if the plan is now stable:
tofu refresh
tofu plan
A clean plan after refresh points to eventual consistency (transient). A plan that still shows the same churn points to a real provider bug.
Step 4: Check the provider version and lockfile
Confirm the version and whether a fix exists upstream:
tofu providers
cat .terraform.lock.hcl | grep -A2 'registry.opentofu.org/hashicorp/aws'
Then bump to a fixed release and re-lock:
tofu init -upgrade
Step 5: Enable trace logging to capture the provider exchange
If it persists, capture the plan/apply payloads for a bug report or deeper diagnosis:
TF_LOG=TRACE tofu apply 2>&1 | tee /tmp/tofu-trace.log
grep -i 'PlannedState\|NewState\|inconsistent' /tmp/tofu-trace.log
Example Root Cause Analysis
A CI tofu apply creating a batch of aws_instance resources failed intermittently — roughly one run in three — with Provider produced inconsistent result after apply, on .private_dns: was "", but now "ip-10-0-...ec2.internal". Local runs almost never hit it.
The team first confirmed the instances were actually being created despite the error:
tofu state list | grep aws_instance
aws_instance.web[0]
aws_instance.web[1]
The resources existed — the apply half-succeeded. A refresh and re-plan came back clean:
tofu refresh && tofu plan
No changes. Your infrastructure matches the configuration.
That pattern — created successfully, clean after refresh, intermittent, timing-correlated — is classic eventual consistency: the AWS provider read private_dns back before the API had populated it, so the post-apply value differed from the planned empty string. It was not corrupting anything; it was a race on a computed attribute.
Two fixes were applied. First, the provider was bumped to a release that marks private_dns as known-after-apply, which removed the planned "":
tofu init -upgrade && tofu providers
+ provider registry.opentofu.org/hashicorp/aws v5.42.0
Second, CI was made idempotent — an apply that trips a transient consistency error is retried once after a short delay, and only a second identical failure is treated as a real provider bug. The intermittent failures stopped.
Prevention Best Practices
- Pin provider versions in
.terraform.lock.hcland keep CI and local on the same version so version-drift bugs cannot appear only in CI. See our infrastructure-as-code guides. - Track your providers’ changelogs; consistency bugs are common and are usually fixed in a point release — upgrade deliberately.
- Make CI applies idempotent: retry a transient consistency error once after a short backoff, and only escalate on a repeated, identical failure.
- Avoid over-using
ignore_changeson computed attributes; it can create the very plan/apply divergence this error reports. - After any failed apply with this error,
tofu refreshand re-plan before assuming the resource is broken — it was often created successfully. - Reproduce with
TF_LOG=TRACEand file a precise upstream issue (resource, attribute, planned vs actual, versions) when it is a genuine provider bug.
Quick Command Reference
# See exactly which attribute diverged
tofu apply 2>&1 | grep -A3 'inconsistent result'
# Check whether the resource was actually created despite the error
tofu state list | grep RESOURCE
tofu state show RESOURCE
# Reconcile state with reality, then re-plan (tests for eventual consistency)
tofu refresh && tofu plan
# Inspect and upgrade the provider version
tofu providers
tofu init -upgrade
# Capture the full provider exchange for a bug report
TF_LOG=TRACE tofu apply 2>&1 | tee /tmp/tofu-trace.log
Conclusion
Provider produced inconsistent result after apply means a provider reported a different attribute value after apply than it planned — a plan/apply consistency violation OpenTofu refuses to accept. The usual root causes:
- Cloud API eventual consistency (an attribute read back too early — transient).
- An outdated or mismatched provider version with a known bug.
- A genuinely computed attribute the provider failed to mark known-after-apply.
- An
ignore_changes/lifecycleinteraction that diverges plan from apply. - Out-of-band mutation changing the resource between plan and post-apply read.
Read the exact attribute that diverged, confirm the resource was created, tofu refresh and re-plan to test for eventual consistency, and pin/upgrade the provider version. Prevent recurrence with locked provider versions, idempotent (retry-once) CI applies, and careful use of ignore_changes so a transient race never wedges your pipeline.
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.