hashicorp/terraform · error

resource has an unsupported mode

Error message

resource %s has an unsupported mode %s

What it means

Thrown by jsonstate.Marshal while serializing the current state to JSON. The switch over resAddr.Mode only maps Managed and Data resources; an ephemeral, list, invalid, or future-mode resource in the state object hits the default branch. Persistent state is only defined for managed/data resources, so an unsupported mode here indicates either an internal bug or a state object that should never have been persisted.

Solutions

  1. Upgrade Terraform so the state serializer handles the mode (or skips it).
  2. Regenerate the state with the same Terraform binary that will read it.
  3. If extending Terraform, add the case or a skip in internal/command/jsonstate/state.go around line 406.
  4. Report upstream with the address and mode string from the message.

Example fix

// before
switch resAddr.Mode {
case addrs.ManagedResourceMode:
	current.Mode = ManagedResourceMode
case addrs.DataResourceMode:
	current.Mode = DataResourceMode
default:
	return ret, fmt.Errorf("resource %s has an unsupported mode %s", resAddr.String(), resAddr.Mode.String())
}

// after
case addrs.EphemeralResourceMode, addrs.ListResourceMode:
	continue // not persisted in JSON state
Defensive patterns

Strategy: validation

Validate before calling

// Before jsonstate.Marshal, drop resources whose mode has no JSON state representation.
func isPersistableMode(m addrs.ResourceMode) bool {
    return m == addrs.ManagedResourceMode || m == addrs.DataResourceMode
}

for _, m := range state.Modules {
    for addr, res := range m.Resources {
        if !isPersistableMode(res.Addr.Resource.Resource.Mode) {
            return fmt.Errorf("state contains non-persistable mode %s on %s", res.Addr.Resource.Resource.Mode, addr)
        }
    }
}

Type guard

func isJSONStateSerializableResource(a addrs.Resource) bool {
    switch a.Mode {
    case addrs.ManagedResourceMode, addrs.DataResourceMode:
        return true
    }
    return false
}

Prevention

When it happens

Trigger: A resource with Ephemeral/List/Invalid mode is present in the in-memory states.State passed to jsonstate.Marshal; a future ResourceMode is added without updating this switch; state built by a divergent Terraform build.

Common situations: Internal/dev build persisting an unsupported mode; state object constructed programmatically (e.g. in tests/tools) with Mode==0; cross-version state consumption.

Related errors


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

Appendix: source

Thrown at internal/command/jsonstate/state.go:406

				Type:         resAddr.Type,
				Name:         resAddr.Name,
				ProviderName: r.ProviderConfig.Provider.String(),
			}

			if k != nil {
				index := k.Value()
				if current.Index, err = ctyjson.Marshal(index, index.Type()); err != nil {
					return nil, err
				}
			}

			switch resAddr.Mode {
			case addrs.ManagedResourceMode:
				current.Mode = ManagedResourceMode
			case addrs.DataResourceMode:
				current.Mode = DataResourceMode
			default:
				return ret, fmt.Errorf("resource %s has an unsupported mode %s",
					resAddr.String(),
					resAddr.Mode.String(),
				)
			}

			schema := schemas.ResourceTypeConfig(
				r.ProviderConfig.Provider,
				resAddr.Mode,
				resAddr.Type,
			)

			// It is possible that the only instance is deposed
			if ri.Current != nil {
				if schema.Version != int64(ri.Current.SchemaVersion) {
					return nil, fmt.Errorf("schema version %d for %s in state does not match version %d from the provider", ri.Current.SchemaVersion, resAddr, schema.Version)
				}

				current.SchemaVersion = ri.Current.SchemaVersion

View on GitHub (pinned to d32a084675)