kubernetes/kops · error

error deleting InstanceTemplate %s: %w

Error message

error deleting InstanceTemplate %s: %w

What it means

This error is returned by DeleteInstanceTemplate when InstanceTemplates().Delete(project, name) fails with anything other than 404 Not Found. It wraps the underlying googleapi error with the template's selfLink. GCE refuses to delete an instance template that is still referenced by an instance group manager, which is the most common cause. Missing templates are treated as already deleted.

Source

Thrown at upup/pkg/fi/cloudup/gce/wrappers.go:81

	return c.WaitForOp(op)
}

// DeleteInstanceTemplate deletes the specified InstanceTemplate (by URL) in GCE
func DeleteInstanceTemplate(c GCECloud, selfLink string) error {
	klog.V(2).Infof("Deleting GCE InstanceTemplate %s", selfLink)
	u, err := ParseGoogleCloudURL(selfLink)
	if err != nil {
		return err
	}

	op, err := c.Compute().InstanceTemplates().Delete(u.Project, u.Name)
	if err != nil {
		if IsNotFound(err) {
			klog.Infof("instancetemplate not found, assuming deleted: %q", selfLink)
			return nil
		}
		return fmt.Errorf("error deleting InstanceTemplate %s: %w", selfLink, err)
	}

	return c.WaitForOp(op)
}

// DeleteInstance deletes the specified instance (by URL) in GCE
func DeleteInstance(c GCECloud, instanceSelfLink string) error {
	klog.V(2).Infof("Deleting GCE Instance %s", instanceSelfLink)
	u, err := ParseGoogleCloudURL(instanceSelfLink)
	if err != nil {
		return err
	}

	op, err := c.Compute().Instances().Delete(u.Project, u.Zone, u.Name)
	if err != nil {
		if IsNotFound(err) {
			klog.Infof("Instance not found, assuming deleted: %q", instanceSelfLink)
			return nil

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped cause: 'being used by' errors mean a MIG still references the template — delete that MIG first, then retry
  2. Verify the credentials/project (GOOGLE_CREDENTIALS, GOOGLE_PROJECT) point at the project owning the template
  3. Grant the service account compute.instanceTemplates.delete (via compute.admin or instanceAdmin roles)
  4. Re-run `kops delete cluster --yes` — 404s are skipped, so it's safe to retry after fixing the blocker
  5. As a last resort, delete the orphaned template manually with `gcloud compute instance-templates delete`

Example fix

// before: delete template without ensuring MIGs are gone
err := DeleteInstanceTemplate(cloud, tmplSelfLink)
// after: ensure dependent MIGs removed first, tolerate not-found
if err := DeleteMIGInstances(cloud, igm); err != nil {
	return err
}
if err := DeleteInstanceGroupManager(cloud, igm); err != nil {
	return err
}
if err := DeleteInstanceTemplate(cloud, tmplSelfLink); err != nil {
	if !isNotFound(err) {
		return err
	}
}
Defensive patterns

Strategy: validation

Validate before calling

// Check no InstanceGroupManager still references the template before deleting it
iggs, err := cloud.Compute().InstanceGroupManagers().AggregatedList(project).Do()
if err != nil {
	return err
}
for _, scoped := range iggs.Items {
	for _, m := range scoped.InstanceGroupManagers {
		if m.InstanceTemplate == tmplSelfLink {
			return fmt.Errorf("template %s still used by MIG %s", tmplSelfLink, m.Name)
		}
	}
}

Type guard

func isTemplateInUse(err error) bool {
	var gerr *googleapi.Error
	return errors.As(err, &gerr) && gerr.Code == 400 && strings.Contains(gerr.Message, "being used")
}

Try / catch

err := gce.DeleteInstanceTemplate(cloud, selfLink)
if err != nil {
	var gerr *googleapi.Error
	if errors.As(err, &gerr) {
		if gerr.Code == 404 {
			return nil // already deleted
		}
		if gerr.Code == 400 && strings.Contains(gerr.Message, "being used") {
			// delete dependent MIGs first, then retry
		}
	}
	return err
}

Prevention

When it happens

Trigger: Calling DeleteInstanceTemplate (from DeleteCloudGroup teardown, after MIGs are deleted) where InstanceTemplates().Delete returns a non-NotFound error: the template is still in use by an existing/lingering InstanceGroupManager, IAM permission denial, invalid project, or transient API 5xx.

Common situations: Template-in-use errors because a previous teardown step (MIG deletion) partially failed or another cluster/tool still references the template; wrong project id in credentials so the template lookup/delete hits a different project; service account without compute.instanceTemplates.delete permission; stale template selfLinks pointing at already-deprecated resources.

Related errors


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