hashicorp/terraform · error
error reading output values
Error message
error reading output values: %s
What it means
After parsing the state file, Put calls jsonstate.MarshalOutputs on stateFile.State.RootOutputValues to derive the JSON output map TFC stores alongside the state. Failure here means the in-memory state's output values can't be converted to the JSON-serializable form TFC expects.
Solutions
- Use a Terraform build where core's output types and jsonstate.MarshalOutputs are in sync (rebuild/pin a consistent version).
- Reduce outputs to plain primitive types to isolate which output value triggers the marshal failure.
- Report the failing output type/marking — this is generally an internal bug, not a config-level fix.
Defensive patterns
Strategy: try-catch
Try / catch
// Capture the marshal error and degrade gracefully
ov, err := jsonstate.MarshalOutputs(s.RootOutputValues)
if err != nil {
log.Printf("output marshal failed (%v); uploading state without JSON outputs", err)
ov = nil // proceed with nil outputs rather than aborting
} Prevention
- Keep core and jsonstate versions aligned (don't mix fork components).
- Prefer plain primitive outputs when integrating with downstream consumers.
- Report persistent marshal failures with the output type detail.
When it happens
Trigger: jsonstate.MarshalOutputs returns an error: an output value has a type or marked-sensitive shape the marshaler can't handle (e.g. a value type introduced in a newer core than the jsonstate package understands), or internal state struct invariants are violated.
Common situations: Version mismatch where core produced outputs (new cty refinement / nested type) that the bundled jsonstate MarshalOutputs can't encode; experimental features in use; corrupted in-memory state after a partial refresh.
Related errors
- error converting output values to json
- error reading state
- Error checking remote Terraform version
- Error downloading state
- Error retrieving state
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/0a2121704241f7ef.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote/backend_state.go:122
return fmt.Errorf("error uploading state in compatibility mode: %v", err)
}
return err
}
// Put the remote state.
func (r *remoteClient) Put(state []byte) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
ctx := context.Background()
// Read the raw state into a Terraform state.
stateFile, err := statefile.Read(bytes.NewReader(state))
if err != nil {
return diags.Append(fmt.Errorf("error reading state: %s", err))
}
ov, err := jsonstate.MarshalOutputs(stateFile.State.RootOutputValues)
if err != nil {
return diags.Append(fmt.Errorf("error reading output values: %s", err))
}
o, err := json.Marshal(ov)
if err != nil {
return diags.Append(fmt.Errorf("error converting output values to json: %s", err))
}
options := tfe.StateVersionUploadOptions{
StateVersionCreateOptions: tfe.StateVersionCreateOptions{
Lineage: tfe.String(stateFile.Lineage),
Serial: tfe.Int64(int64(stateFile.Serial)),
MD5: tfe.String(fmt.Sprintf("%x", md5.Sum(state))),
Force: tfe.Bool(r.forcePush),
JSONStateOutputs: tfe.String(base64.StdEncoding.EncodeToString(o)),
},
RawState: state,
}
// If we have a run ID, make sure to add it to the optionsView on GitHub (pinned to d32a084675)