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
- Upgrade Terraform so the state serializer handles the mode (or skips it).
- Regenerate the state with the same Terraform binary that will read it.
- If extending Terraform, add the case or a skip in internal/command/jsonstate/state.go around line 406.
- 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
- Never persist ephemeral/list resources in a states.State passed to jsonstate.Marshal.
- Keep the state serializer's mode switch in sync with internal/addrs.
- When building state programmatically (tests/tools), set Mode explicitly to Managed or Data.
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
- resource has an unsupported mode
- resource has an unsupported mode
- preparing attribute values for
- preparing identity values for
- resource has an unsupported action reason
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.SchemaVersionView on GitHub (pinned to d32a084675)