hashicorp/terraform · error
could not decode output
Error message
could not decode output %s (ID %s)
What it means
Thrown by GetRootOutputValues when tfeOutputToCtyValue fails to convert a TFE state version output into a cty.Value. Note this error does NOT use %w — the underlying cause (marshal failure, type-interpret failure, or value-coercion failure from errors 536/537/538) is intentionally dropped, showing only the output name and ID. This makes root-cause diagnosis harder without terraform debug logs.
Solutions
- Enable TF_LOG=DEBUG to see which sub-error (536/537/538) triggered inside tfeOutputToCtyValue, since this wrapper drops the cause
- Upgrade terraform and all providers to compatible, current versions
- If one output is identified, remove or correct it in configuration and re-apply to overwrite the bad output
- As a last resort, use terraform state pull, manually inspect the offending output, and terraform state push a corrected state
Defensive patterns
Strategy: try-catch
Validate before calling
// Before calling GetRootOutputValues, probe-decode each output if you have the raw data:
// (Not always feasible since tfeOutputToCtyValue is internal; rely on TF_LOG=DEBUG instead.)
os.Setenv("TF_LOG", "DEBUG") // surface which sub-error (536/537/538) caused the decode failure Try / catch
outputs, err := state.GetRootOutputValues(ctx)
if err != nil && strings.Contains(err.Error(), "could not decode output") {
// The underlying cause is dropped (no %w). Enable TF_LOG=DEBUG to get details.
return nil, fmt.Errorf("output decode failed (enable TF_LOG=DEBUG for root cause): %s", err.Error())
}
return outputs, err Prevention
- Keep terraform and provider versions aligned and current to avoid type-encoding incompatibilities
- When this error appears, immediately enable TF_LOG=DEBUG since the wrapper drops the underlying cause
- After provider upgrades, test output decoding on a staging workspace before production
When it happens
Trigger: Any failure inside tfeOutputToCtyValue: json.Marshal of DetailedType fails, cty.Type.UnmarshalJSON cannot parse the type, or gocty.ToCtyValue cannot coerce the value to the type; a corrupted or schema-incompatible output in the remote state.
Common situations: State written by one terraform/provider version being read by an incompatible version; an output whose type schema changed across provider versions; corrupted state version output data from a partial/failed upload.
Related errors
- could not interpret output
- could not marshal output
- could not interpret value
- canceled reading current outputs
- could not read state version output
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/002c9a50cb092f70.
Report an issue: GitHub.
Appendix: source
Thrown at internal/cloud/state.go:612
return nil, ErrStateVersionUnauthorizedUpgradeState
}
return state.RootOutputValues, nil
}
if output.Sensitive {
// Since this is a sensitive value, the output must be requested explicitly in order to
// read its value, which is assumed to be present by callers
sensitiveOutput, err := s.tfeClient.StateVersionOutputs.Read(ctx, output.ID)
if err != nil {
return nil, fmt.Errorf("could not read state version output %s: %w", output.ID, err)
}
output.Value = sensitiveOutput.Value
}
cval, err := tfeOutputToCtyValue(*output)
if err != nil {
return nil, fmt.Errorf("could not decode output %s (ID %s)", output.Name, output.ID)
}
result[output.Name] = &states.OutputValue{
Value: cval,
Sensitive: output.Sensitive,
}
}
return result, nil
}
func clamp(val, min, max int64) int64 {
if val < min {
return min
} else if val > max {
return max
}
return valView on GitHub (pinned to d32a084675)