hashicorp/terraform · critical

found unrecognized resource mode:

Error message

found unrecognized resource mode: 

What it means

A panic in `Plan.getSchema` (internal/command/jsonformat/plan.go:50) triggered when a resource change's `Mode` field matches neither `ManagedResourceMode` nor `DataResourceMode`. The default case of the switch concatenates the unknown mode into the panic message. It is an internal invariant: every resource change in a well-formed plan JSON must be either managed or data. Hitting it means the plan JSON is malformed or produced by an incompatible Terraform version.

Source

Thrown at internal/command/jsonformat/plan.go:50

	OutputChanges      map[string]jsonplan.Change        `json:"output_changes,omitempty"`
	ResourceChanges    []jsonplan.ResourceChange         `json:"resource_changes,omitempty"`
	ResourceDrift      []jsonplan.ResourceChange         `json:"resource_drift,omitempty"`
	RelevantAttributes []jsonplan.ResourceAttr           `json:"relevant_attributes,omitempty"`
	DeferredChanges    []jsonplan.DeferredResourceChange `json:"deferred_changes,omitempty"`
	ActionInvocations  []jsonplan.ActionInvocation       `json:"action_invocations,omitempty"`

	ProviderFormatVersion string                            `json:"provider_format_version"`
	ProviderSchemas       map[string]*jsonprovider.Provider `json:"provider_schemas,omitempty"`
}

func (plan Plan) getSchema(change jsonplan.ResourceChange) *jsonprovider.Schema {
	switch change.Mode {
	case jsonstate.ManagedResourceMode:
		return plan.ProviderSchemas[change.ProviderName].ResourceSchemas[change.Type]
	case jsonstate.DataResourceMode:
		return plan.ProviderSchemas[change.ProviderName].DataSourceSchemas[change.Type]
	default:
		panic("found unrecognized resource mode: " + change.Mode)
	}
}

func (plan Plan) getActionSchema(ai jsonplan.ActionInvocation) *jsonprovider.ActionSchema {
	return plan.ProviderSchemas[ai.ProviderName].ActionSchemas[ai.Type]
}

func (plan Plan) renderHuman(renderer Renderer, mode plans.Mode, opts ...plans.Quality) {
	checkOpts := func(target plans.Quality) bool {
		return slices.Contains(opts, target)
	}

	diffs := precomputeDiffs(plan, mode)
	haveRefreshChanges := renderHumanDiffDrift(renderer, diffs, mode)

	willPrintResourceChanges := false
	counts := make(map[plans.Action]int)
	importingCount := 0

View on GitHub (pinned to c9def3e214)

Solutions

  1. Regenerate the plan with the same Terraform version used to render or apply it, and never downgrade across a plan.
  2. If using `terraform show -json` output programmatically, validate `resource_changes[].mode` is in {managed, data} before processing.
  3. Report as a Terraform bug if reproduced with unmodified stock Terraform and a freshly generated plan.
  4. Avoid hand-editing or rewriting plan JSON files; treat plans as opaque artifacts.

Example fix

// before: consuming plan JSON without validation
for _, rc := range planJSON["resource_changes"].([]interface{}) {
    schema := getSchema(rc) // panics on unknown mode
}

// after: validate mode before dispatching
for _, rc := range planJSON["resource_changes"].([]interface{}) {
    mode := rc.(map[string]interface{})["mode"].(string)
    if mode != "managed" && mode != "data" {
        return fmt.Errorf("unsupported resource mode %q; regenerate plan with current terraform", mode)
    }
    schema := getSchema(rc)
}
Defensive patterns

Strategy: validation

Validate before calling

// Go: validate plan JSON modes before passing to jsonformat rendering
func validateResourceModes(planJSON []byte) error {
	var p struct {
		RC []struct{ Mode string `json:"mode"` } `json:"resource_changes"`
	}
	if err := json.Unmarshal(planJSON, &p); err != nil {
		return err
	}
	for _, rc := range p.RC {
		if rc.Mode != "managed" && rc.Mode != "data" {
			return fmt.Errorf("unrecognized resource mode %q; regenerate plan with current terraform", rc.Mode)
		}
	}
	return nil
}

Try / catch

// Go: recover from the jsonformat panic and surface a controlled error
defer func() {
	if r := recover(); r != nil {
		err = fmt.Errorf("plan rendering failed (likely version skew): %v", r)
	}
}()
renderer.Render(plan)

Prevention

When it happens

Trigger: Rendering or applying a JSON plan (`terraform show -json`, `terraform apply tfplan`) where a `resource_changes[].mode` entry holds an unrecognized value (not 'managed' or 'data'). Typically from a hand-edited plan file, a plan produced by a newer Terraform that introduced a new resource mode, or third-party tooling that wrote non-standard JSON.

Common situations: Version skew: generating a plan with Terraform 1.x and rendering/applying it with an older binary; corrupted plan files; tooling that round-trips plan JSON incorrectly; experimental forks of Terraform.

Related errors


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