hashicorp/terraform · error
error in marshaling resource drift
Error message
error in marshaling resource drift: %s
What it means
Top-level propagation error from Marshal: MarshalResourceChanges failed on the drifted-resources subset. Drifted resources are decoded and rendered like other resource changes, so the failure is usually schema or decode related.
Solutions
- Read the wrapped error for the specific resource address.
- Ensure the provider for the drifted resource type is initialized.
- Regenerate the plan so drift reflects current schemas.
- If the resource was removed from config/provider intentionally, refresh state to clear drift.
Defensive patterns
Strategy: validation
Validate before calling
// Confirm each drifted resource has a usable schema before marshaling.
func driftedSchemasOk(drifted []*plans.ResourceInstanceChangeSrc, schemas *terraform.Schemas) error {
for _, d := range drifted {
s := schemas.ResourceTypeConfig(d.ProviderAddr.Provider, d.Addr.Resource.Resource.Mode, d.Addr.Resource.Resource.Type)
if s.Body == nil {
return fmt.Errorf("drifted resource %%s has no schema", d.Addr)
}
}
return nil
} Prevention
- Keep providers for all in-state resources initialized.
- Refresh state to clear drift for resources removed from config/provider.
When it happens
Trigger: A drifted resource instance references a provider schema that is missing or incompatible at render time, or its before/after values fail to decode.
Common situations: Drift detected against resources whose provider was since changed/removed; refresh-only mode plans rendered with a different provider set.
Related errors
- error in marshaling deferred resource changes
- error in marshaling resource changes
- error in marshaling deferred action invocations
- error in marshaling output changes
- error in marshalPlannedValues
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/1fd19558046c639b.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/jsonplan/plan.go:293
// output.ResourceDrift
if len(p.DriftedResources) > 0 {
// In refresh-only mode, we render all resources marked as drifted,
// including those which have moved without other changes. In other plan
// modes, move-only changes will be included in the planned changes, so
// we skip them here.
var driftedResources []*plans.ResourceInstanceChangeSrc
if p.UIMode == plans.RefreshOnlyMode {
driftedResources = p.DriftedResources
} else {
for _, dr := range p.DriftedResources {
if dr.Action != plans.NoOp {
driftedResources = append(driftedResources, dr)
}
}
}
output.ResourceDrift, err = MarshalResourceChanges(driftedResources, schemas)
if err != nil {
return nil, fmt.Errorf("error in marshaling resource drift: %s", err)
}
}
if err := output.marshalRelevantAttrs(p); err != nil {
return nil, fmt.Errorf("error marshaling relevant attributes for external changes: %s", err)
}
// output.ResourceChanges
if p.Changes != nil {
output.ResourceChanges, err = MarshalResourceChanges(p.Changes.Resources, schemas)
if err != nil {
return nil, fmt.Errorf("error in marshaling resource changes: %s", err)
}
}
if p.DeferredResources != nil {
output.DeferredChanges, err = MarshalDeferredResourceChanges(p.DeferredResources, schemas)
if err != nil {View on GitHub (pinned to d32a084675)