hashicorp/terraform · error

error reading output values: %s

Error message

error reading output values: %s

What it means

Emitted by remoteClient.Put (backend_state.go:120-123) when jsonstate.MarshalOutputs cannot serialize the RootOutputValues from the parsed state file. MarshalOutputs converts the in-memory state outputs into the JSON representation stored alongside the state version in TFC. Failure means the output values in the state could not be converted to that JSON model.

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 options

View on GitHub (pinned to c9def3e214)

Solutions

  1. Use a Terraform build whose jsonstate package matches the state format version that wrote the outputs.
  2. Regenerate state from scratch (import resources) if the outputs are irrecoverably malformed.
  3. Inspect the wrapped %s diagnostic to see which output value/type MarshalOutputs rejected, then fix or remove that output in config.
  4. If migrating versions, upgrade Terraform CLI rather than downgrading, to pick up newer output type support.

Example fix

// before
Error: error reading output values: unsupported marker type "SensitiveObject"

// after: upgrade Terraform to a version supporting the output type, then re-apply
$ terraform version  # ensure >= version that wrote the state
$ terraform apply
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the state format version is one this build understands before marshaling.
if stateFile == nil || stateFile.State == nil {
    return errors.New("cannot marshal outputs from empty state")
}
if stateFile.TerraformVersion != nil && unsupportedVersion(stateFile.TerraformVersion) {
    return fmt.Errorf("state written by unsupported version %s", stateFile.TerraformVersion)
}

Prevention

When it happens

Trigger: The state's RootOutputValues contain a value shape MarshalOutputs cannot handle — typically a state-format-version mismatch where outputs carry types/markers the jsonstate package in this build does not recognize.

Common situations: State written by a newer Terraform with extended value types, read by an older build; a provider produced an output value with an unusual cty type; partial/legacy state from an older schema.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/0a2121704241f7ef. Report an issue: GitHub.