hashicorp/terraform · error

resource %s has an unsupported mode %s

Error message

resource %s has an unsupported mode %s

What it means

Thrown by the JSON plan values builder when a resource instance's address mode is neither addrs.ManagedResourceMode nor addrs.DataResourceMode. Terraform only defines those two resource modes, so the default branch of the switch is unreachable under normal operation and signals an internal inconsistency in the planned changes structure.

Source

Thrown at internal/command/jsonplan/values.go:191

		if r.Action == plans.Delete || r.Action == plans.Forget {
			continue
		}

		resource := resource{
			Address:      r.Addr.String(),
			Type:         r.Addr.Resource.Resource.Type,
			Name:         r.Addr.Resource.Resource.Name,
			ProviderName: r.ProviderAddr.Provider.String(),
			Index:        r.Addr.Resource.Key,
		}

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

		schema := schemas.ResourceTypeConfig(
			r.ProviderAddr.Provider,
			r.Addr.Resource.Resource.Mode,
			resource.Type,
		)
		if schema.Body == nil {
			return nil, fmt.Errorf("no schema found for %s", r.Addr.String())
		}
		resource.SchemaVersion = uint64(schema.Version)
		changeV, err := r.Decode(schema)
		if err != nil {
			return nil, err
		}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Upgrade to the latest stable Terraform release that is compatible with your provider versions.
  2. Reproduce with `terraform plan` (non-JSON) to confirm the plan itself is valid; if it succeeds, the bug is in the JSON renderer.
  3. Report the issue to hashicorp/terraform with the plan file and provider versions.
  4. Regenerate the plan from scratch (`terraform plan -out=new.tfplan`) in case the plan file was produced by a mismatched/older Terraform binary.
Defensive patterns

Strategy: try-catch

Type guard

// Confirm a resource address mode is renderable before JSON plan marshaling.
func isRenderableMode(m addrs.ResourceMode) bool {
    return m == addrs.ManagedResourceMode || m == addrs.DataResourceMode
}

Try / catch

if _, err := jsonplan.MarshalPlannedResourceChange(r, schemas); err != nil {
    // Render human-readable plan instead; surface as a Terraform-internal bug.
    return err
}

Prevention

When it happens

Trigger: Reached when jsonplan marshals planned resource changes (changes.ResourceInstance iteration) and r.Addr.Resource.Resource.Mode returns a value outside {managed, data}. Occurs during `terraform show -json <plan>` or `terraform plan -json` rendering for a resource whose mode string is empty or unknown.

Common situations: Points to a Terraform Core bug where a resource change was recorded with an uninitialized or custom Mode value. Occasionally seen with very new/preview resource mode features or corrupted in-memory plan objects. Not caused by ordinary HCL configuration errors.

Related errors


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