Error: Provider produced inconsistent result after apply
Fixes OpenTofu's 'Error: Provider produced inconsistent result after apply' by pinning the provider past the regression or avoiding the broken attribute. Use when apply fails naming an attribute whose post-apply value differs from the plan. Not for plan-time diffs or provider install errors.
TL;DR: The provider's post-apply read returned a value different from what it planned, and tofu refuses to record the lie. The error names the exact attribute. This is a provider bug, not your config: the usual escapes are pinning the provider to a version without the regression, or restructuring config to avoid the broken attribute.
Error: Provider produced inconsistent result after apply
When applying changes to libvirt_domain.sandbox, provider
"provider["registry.opentofu.org/dmacvicar/libvirt"]" produced an
unexpected new value: .devices.interfaces[0].wait_for_ip: was null, but now
cty.ObjectVal(map[string]cty.Value{"source":cty.StringVal("lease"),
"timeout":cty.NullVal(cty.Number)}).
This is a bug in the provider, which should be reported in the provider's
own issue tracker.Steps
- Read the attribute path in the error (
.devices.interfaces[0].wait_for_ipabove). That's the attribute whose readback disagrees with the plan.
Expected: you can point at one attribute.
- Check whether you recently upgraded the provider. If so, pin the last known good version in
required_providers, e.g.version = "= 0.9.7", thentofu init -upgrade.
Expected: init reinstalls the older provider; re-running apply succeeds.
- If no recent upgrade, check the provider's issue tracker for this exact attribute. Provider regressions cluster around null-vs-empty transitions and set ordering.
Expected: either an upstream fix to upgrade to, or a confirmed open bug.
- As a last resort, restructure to avoid the broken attribute (drop the optional block, or set it to the value the provider actually returns).
Expected: apply completes without the inconsistency error.
- Report it to the provider's own tracker with the verbatim error. The message tells you to.
Expected: an upstream issue number you can watch for the real fix.
When this applies
tofu applyfails AFTER creating or updating the resource, naming an attribute withwas X, but now Y.- It started right after a provider version bump.
When it doesn't apply
- Plan-time diffs on every run are drift or a noisy provider, not this error.
Error: Provider produced inconsistent final planhappens at plan time and is a different check.Error: Failed to install provideris an install problem, not a readback problem.
Tool versions
All OpenTofu versions. The check is enforced by the plugin framework, so it depends on the provider, not on tofu.
Why it happens
The provider framework requires the state after apply to match the planned values. When the provider's own read returns something different (stale value, wrong null handling, reordered set), tofu can't tell which side is true, so it fails loudly instead of recording a state it can't trust.
Edge cases
ignore_changesdoes NOT fix this. It suppresses plan diffs, but the post-apply consistency check still compares against the plan.- Null-vs-empty-string is the classic trigger:
was ""but nownull(or the reverse) fails the check even though both mean "empty" to a human. - Don't "fix" it by deleting the resource from state and re-importing. The next apply will fail the same way until the provider is fixed or pinned.
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.