hashicorp/terraform · error

resource %s has an unsupported mode %s

Error message

resource %s has an unsupported mode %s

What it means

marshalResourceChange switches on addr.Resource.Resource.Mode; only ManagedResourceMode and DataResourceMode are handled. Any other mode hits the default. The addrs package only defines these two modes for resources, so this is effectively an internal invariant violation rather than a configuration issue.

Source

Thrown at internal/command/jsonplan/plan.go:611

	if key != nil {
		if key == addrs.WildcardKey {
			// The wildcard key should only be set for a deferred instance.
			r.IndexUnknown = true
		} else {
			value := key.Value()
			if r.Index, err = ctyjson.Marshal(value, value.Type()); err != nil {
				return r, err
			}
		}
	}

	switch addr.Resource.Resource.Mode {
	case addrs.ManagedResourceMode:
		r.Mode = jsonstate.ManagedResourceMode
	case addrs.DataResourceMode:
		r.Mode = jsonstate.DataResourceMode
	default:
		return r, fmt.Errorf("resource %s has an unsupported mode %s", r.Address, addr.Resource.Resource.Mode.String())
	}
	r.ModuleAddress = addr.Module.String()
	r.Name = addr.Resource.Resource.Name
	r.Type = addr.Resource.Resource.Type
	r.ProviderName = rc.ProviderAddr.Provider.String()

	switch rc.ActionReason {
	case plans.ResourceInstanceChangeNoReason:
		r.ActionReason = "" // will be omitted in output
	case plans.ResourceInstanceReplaceBecauseCannotUpdate:
		r.ActionReason = ResourceInstanceReplaceBecauseCannotUpdate
	case plans.ResourceInstanceReplaceBecauseTainted:
		r.ActionReason = ResourceInstanceReplaceBecauseTainted
	case plans.ResourceInstanceReplaceByRequest:
		r.ActionReason = ResourceInstanceReplaceByRequest
	case plans.ResourceInstanceReplaceByTriggers:
		r.ActionReason = ResourceInstanceReplaceByTriggers
	case plans.ResourceInstanceDeleteBecauseNoResourceConfig:

View on GitHub (pinned to c9def3e214)

Solutions

  1. Report as an internal bug; it is not user-fixable through HCL.
  2. Ensure you are using a single consistent, released Terraform build.
  3. If maintaining a fork that added a mode, add a case in plan.go:605.
Defensive patterns

Strategy: type-guard

Type guard

func supportedResourceMode(m addrs.ResourceMode) bool {
    return m == addrs.ManagedResourceMode || m == addrs.DataResourceMode
}

// use before marshaling
for _, rc := range plan.Changes.Resources {
    if !supportedResourceMode(rc.Addr.Resource.Resource.Mode) {
        return fmt.Errorf("unsupported resource mode %s for %s", rc.Addr.Resource.Resource.Mode, rc.Addr)
    }
}

Prevention

When it happens

Trigger: A resource instance whose mode is neither managed nor data is present in the changes. Only reachable if a new resource mode is added to addrs without renderer support, or via a custom build.

Common situations: Very rare. Indicates a Terraform core change introducing a new resource mode not yet handled by jsonplan, or a fork with an extra mode.

Related errors


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