kubernetes/kops · error

unexpected target type for deletion: %T

Error message

unexpected target type for deletion: %T

What it means

deleteForwardingRule.Delete is invoked by the fi executor with a target it was configured with. It asserts that the target is a *gce.GCEAPITarget (the only target that can talk to the GCE Compute API) and returns this error for any other target type (e.g. a dry-run/terraform target). It is an internal invariant check, not a cloud API failure.

Source

Thrown at upup/pkg/fi/cloudup/gcetasks/forwardingrule.go:397

var _ fi.CloudupDeletion = (*deleteForwardingRule)(nil)

// TaskName returns the task name
func (d *deleteForwardingRule) TaskName() string {
	return "ForwardingRule"
}

// Item returns the forwarding rule name
func (d *deleteForwardingRule) Item() string {
	return d.forwardingRule.Name
}

func (d *deleteForwardingRule) Delete(t fi.CloudupTarget) error {
	ctx := context.TODO()

	gceTarget, ok := t.(*gce.GCEAPITarget)
	if !ok {
		return fmt.Errorf("unexpected target type for deletion: %T", t)
	}

	cloud := gceTarget.Cloud
	name := d.forwardingRule.Name

	if _, err := cloud.Compute().ForwardingRules().Delete(ctx, cloud.Project(), cloud.Region(), name); err != nil {
		return fmt.Errorf("deleting forwardingRule %s: %w", name, err)
	}

	return nil
}

// String returns a string representation of the task
func (d *deleteForwardingRule) String() string {
	return d.TaskName() + "-" + d.Item()
}

func (d *deleteForwardingRule) DeferDeletion() bool {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Run apply with the real GCE API target (omit --target or use --target=direct) so deletes execute against a *gce.GCEAPITarget
  2. Check how the fi.Target is constructed for your apply/run and ensure the GCE cloud target is passed for GCE clusters
  3. If using a dry-run/terraform target, ensure the task's delete path is not invoked (or update the task to support that target type)

Example fix

// before (programmatic use, wrong target)
target := fi.NewDryRunTarget(cloud, os.Stdout)
context.Target = target
// after
context.Target = gce.NewGCEAPITarget(cloud)
Defensive patterns

Strategy: type-guard

Validate before calling

// verify the target before running deletes for GCE tasks
if _, ok := target.(*gce.GCEAPITarget); !ok {
	return fmt.Errorf("GCE deletion requires GCEAPITarget, got %T", target)
}

Type guard

func asGCEAPITarget(t fi.CloudupTarget) (*gce.GCEAPITarget, bool) {
	tgt, ok := t.(*gce.GCEAPITarget)
	return tgt, ok
}

Try / catch

if err := task.Delete(target); err != nil {
	if strings.Contains(err.Error(), "unexpected target type") {
		// wrong executor target; switch to the GCE API target and retry
	}
}

Prevention

When it happens

Trigger: The fi framework runs Delete against a CloudupTarget that is not *gce.GCEAPITarget — typically when the executor is running with a target like TargetTerraform/TargetDryRun that reaches a delete path, or a target from a different cloud provider is passed due to executor misconfiguration.

Common situations: Running kops with --target=terraform or --target=dry-run while the model still resolves a deletion of a GCE forwarding rule; mixing targets when programmatically driving fi.Apply; tests passing a mock target of the wrong concrete type.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/4f0d4b42d508b094. Report an issue: GitHub.