hashicorp/terraform · error

resource %s has an unsupported mode %s

Error message

resource %s has an unsupported mode %s

What it means

Returned by jsonconfig.marshalResources when a configs.Resource has a Mode that is neither ManagedResourceMode nor DataResourceMode (config.go:482-489). Resource modes are an enumerated set, so reaching the default branch means an unhandled mode value. The message names the resource address and the offending mode string, and is treated as an internal invariant violation.

Source

Thrown at internal/command/jsonconfig/config.go:488

func marshalResources(resources map[string]*configs.Resource, schemas *terraform.Schemas, moduleAddr string) ([]resource, error) {
	var rs []resource
	for _, v := range resources {
		providerConfigKey := opaqueProviderKey(v.ProviderConfigAddr().StringCompact(), moduleAddr)
		r := resource{
			Address:           v.Addr().String(),
			Type:              v.Type,
			Name:              v.Name,
			ProviderConfigKey: providerConfigKey,
		}

		switch v.Mode {
		case addrs.ManagedResourceMode:
			r.Mode = "managed"
		case addrs.DataResourceMode:
			r.Mode = "data"
		default:
			return rs, fmt.Errorf("resource %s has an unsupported mode %s", r.Address, v.Mode.String())
		}

		cExp := marshalExpression(v.Count)
		if !cExp.Empty() {
			r.CountExpression = &cExp
		} else {
			fExp := marshalExpression(v.ForEach)
			if !fExp.Empty() {
				r.ForEachExpression = &fExp
			}
		}

		schema := schemas.ResourceTypeConfig(
			v.Provider,
			v.Mode,
			v.Type,
		)
		if schema.Body == nil {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Upgrade terraform CLI to a version whose jsonconfig knows about the resource mode in use.
  2. Downgrade the configuration/state to a version compatible with the running CLI.
  3. If developing a new resource mode, add the case to marshalResources before exercising show -json.
  4. Report as a Terraform bug with the resource address and mode string from the error.
Defensive patterns

Strategy: type-guard

Validate before calling

// Before marshalling, confirm all resource modes are known to the marshaler.
for _, r := range module.Resources() {
    if r.Mode != addrs.ManagedResourceMode && r.Mode != addrs.DataResourceMode {
        return fmt.Errorf("unsupported resource mode %q on %s; upgrade terraform", r.Mode, r.Addr())
    }
}

Type guard

// isMarshalableResourceMode narrows to the modes jsonconfig supports.
func isMarshalableResourceMode(m addrs.ResourceMode) bool {
    return m == addrs.ManagedResourceMode || m == addrs.DataResourceMode
}

Prevention

When it happens

Trigger: Producing JSON config output (`terraform show -json` / jsonconfig.Marshal) for a configuration whose resources carry a mode the marshaler does not recognize — e.g. a future Terraform version introduces a new resource mode (such as action/ephemeral) before the jsonconfig package is updated, or internal state/config is constructed with an out-of-range mode value.

Common situations: Version skew: running a newer terraform state/config with an older build of the CLI; custom tooling that fabricates configs.Resource values with invalid modes; in-development features that add modes without updating marshalers.

Related errors


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