hashicorp/terraform · error

Error: unsupported resource %s

Error message

Error: unsupported resource %s

What it means

Returned by `MoveResourceState` (provider.go:213) when `req.TargetTypeName` is not `terraform_data`. The built-in provider's only managed resource is `terraform_data`, so any other move target is unsupported. Unlike the data-source guards, this can be hit legitimately via a `moved` block targeting the wrong resource type.

Source

Thrown at internal/builtin/providers/terraform/provider.go:213

// ImportResourceState requests that the given resource be imported.
func (p *Provider) ImportResourceState(req providers.ImportResourceStateRequest) providers.ImportResourceStateResponse {
	if req.TypeName == "terraform_data" {
		return importDataStore(req)
	}

	panic("unimplemented: cannot import resource type " + req.TypeName)
}

// MoveResourceState requests that the given resource be moved.
func (p *Provider) MoveResourceState(req providers.MoveResourceStateRequest) providers.MoveResourceStateResponse {
	switch req.TargetTypeName {
	case "terraform_data":
		return moveDataStoreResourceState(req)
	default:
		var resp providers.MoveResourceStateResponse

		resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("Error: unsupported resource %s", req.TargetTypeName))

		return resp
	}
}

// ValidateResourceConfig is used to to validate the resource configuration values.
func (p *Provider) ValidateResourceConfig(req providers.ValidateResourceConfigRequest) providers.ValidateResourceConfigResponse {
	return validateDataStoreResourceConfig(req)
}

func (p *Provider) ValidateEphemeralResourceConfig(req providers.ValidateEphemeralResourceConfigRequest) providers.ValidateEphemeralResourceConfigResponse {
	var resp providers.ValidateEphemeralResourceConfigResponse
	resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("unsupported ephemeral resource type %q", req.TypeName))
	return resp
}

// OpenEphemeralResource implements providers.Interface.
func (p *Provider) OpenEphemeralResource(req providers.OpenEphemeralResourceRequest) providers.OpenEphemeralResourceResponse {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Target `terraform_data` for any move into the built-in terraform provider.
  2. Confirm `TargetTypeName` is present in `GetProviderSchema().ResourceTypes` (only `terraform_data`).
  3. If the destination resource lives in another provider, point the `moved` block at that provider's address.
  4. Update state-migration scripts that hard-code an old resource type.

Example fix

// before
moved {
  from = aws_instance.old
  to   = terraform_placeholder.x
}

// after
moved {
  from = aws_instance.old
  to   = terraform_data.x
}
Defensive patterns

Strategy: validation

Validate before calling

schema := provider.GetProviderSchema()
if _, ok := schema.ResourceTypes[req.TargetTypeName]; !ok {
    return fmt.Errorf("cannot move to %s: not a managed resource of the terraform provider", req.TargetTypeName)
}

Type guard

func providerSupportsResource(schema providers.GetProviderSchemaResponse, name string) bool {
    _, ok := schema.ResourceTypes[name]
    return ok
}

Prevention

When it happens

Trigger: A configuration uses a `moved` block whose destination address points to a `terraform_*` resource type other than `terraform_data`, e.g. `moved { from = ... ; to = terraform_legacy.x }`, or a `MoveResourceStateRequest` is dispatched with an unrecognised `TargetTypeName`.

Common situations: Migrating state into the built-in provider with a typo'd or renamed resource type; tooling that auto-generates `moved` blocks using a stale type name; attempting to move to a removed/deprecated resource type.

Related errors


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