hashicorp/terraform · error
error in marshalPlanVariables: %s
Error message
error in marshalPlanVariables: %s
What it means
Top-level wrapper: output.marshalPlanVariables failed while serializing the plan's variables section. The inner failure is either a DynamicValue decode of a variable value (v.Decode(cty.DynamicPseudoType)) or a ctyjson.Marshal of a variable value or its default.
Source
Thrown at internal/command/jsonplan/plan.go:266
}
// Marshal returns the json encoding of a terraform plan.
func Marshal(
config *configs.Config,
p *plans.Plan,
sf *statefile.File,
schemas *terraform.Schemas,
) ([]byte, error) {
output := newPlan()
output.TerraformVersion = version.String()
output.Timestamp = p.Timestamp.Format(time.RFC3339)
output.Applyable = p.Applyable
output.Complete = p.Complete
output.Errored = p.Errored
err := output.marshalPlanVariables(p.VariableValues, config.Module.Variables)
if err != nil {
return nil, fmt.Errorf("error in marshalPlanVariables: %s", err)
}
// output.PlannedValues
err = output.marshalPlannedValues(p.Changes, schemas)
if err != nil {
return nil, fmt.Errorf("error in marshalPlannedValues: %s", err)
}
// 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 {View on GitHub (pinned to c9def3e214)
Solutions
- Regenerate the plan with the current Terraform binary so variable encoding matches.
- Inspect the wrapped inner error to find which variable failed.
- Simplify or check unusual variable types (e.g. deeply nested object types) in the root module.
Defensive patterns
Strategy: try-catch
Try / catch
out, err := jsonplan.Marshal(config, plan, sf, schemas)
if err != nil {
// 'error in marshalPlanVariables' wraps the variable-specific failure;
// log err and inspect the inner message to find the offending variable.
return err
} Prevention
- Produce and render plans with the same Terraform version.
- Avoid unusual/recursive variable types that may not survive ctyjson round-tripping.
- Validate variable values against their declared types before planning.
When it happens
Trigger: Reached on every full Marshal call. marshalPlanVariables iterates p.VariableValues, decoding each DynamicValue and re-marshaling to JSON; any decode/type error or non-JSON-serializable value aborts and is wrapped here.
Common situations: Plan saved by a Terraform version that encoded variables in a form the current binary cannot decode; a variable whose value is of a cty type ctyjson cannot represent; corrupted plan file.
Related errors
- error finding remote workspace: %w
- error loading variables: %w
- error loading config with snapshot: %w
- error finding remote workspace: %w
- error loading workspace: %w
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/ddc281b0207dd57a.
Report an issue: GitHub.