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

  1. Enable TF_LOG=DEBUG to see which sub-error (536/537/538) triggered inside tfeOutputToCtyValue, since this wrapper drops the cause
  2. Upgrade terraform and all providers to compatible, current versions
  3. If one output is identified, remove or correct it in configuration and re-apply to overwrite the bad output
  4. 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

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


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 val

View on GitHub (pinned to d32a084675)