kubernetes/kops · error
error deleting Subnetwork %s: %v
Error message
error deleting Subnetwork %s: %v
What it means
Thrown by deleteSubnet in pkg/resources/gce/gce.go when the GCE Compute Subnetworks().Delete API returns an error other than NotFound (which is treated as already-deleted success). The message wraps the subnetwork self-link and the underlying Google API error. It signals cluster teardown failed to remove the subnetwork resource.
Source
Thrown at pkg/resources/gce/gce.go:952
}
func deleteSubnet(cloud fi.Cloud, r *resources.Resource) error {
c := cloud.(gce.GCECloud)
o := r.Obj.(*compute.Subnetwork)
klog.V(2).Infof("deleting GCE Subnetwork %s", o.SelfLink)
u, err := gce.ParseGoogleCloudURL(o.SelfLink)
if err != nil {
return err
}
op, err := c.Compute().Subnetworks().Delete(u.Project, u.Region, u.Name)
if err != nil {
if gce.IsNotFound(err) {
klog.Infof("Subnetwork not found, assuming deleted: %q", o.SelfLink)
return nil
}
return fmt.Errorf("error deleting Subnetwork %s: %v", o.SelfLink, err)
}
return c.WaitForOp(op)
}
func (d *clusterDiscoveryGCE) listRouters() ([]*resources.Resource, error) {
c := d.gceCloud
var resourceTrackers []*resources.Resource
ctx := context.Background()
routers, err := c.Compute().Routers().List(ctx, c.Project(), c.Region())
if err != nil {
return nil, fmt.Errorf("error listing routers: %v", err)
}
for _, o := range routers {
if !d.matchesClusterName(o.Name) {View on GitHub (pinned to 4c8573c808)
Solutions
- Inspect the wrapped %v error to find the root cause (403 permission, 400 failedPrecondition 'still in use', 429 rate limit, 5xx).
- Delete dependent resources first (forwarding rules, target pools, instances using the subnet), then retry deletion.
- Grant the service account compute.networkAdmin (or compute.subnetworks.delete permission) in the project.
- Retry after backoff if the cause is a transient 429/5xx; kops delete cluster is idempotent (NotFound is tolerated).
Example fix
// before
return fmt.Errorf("error deleting Subnetwork %s: %v", o.SelfLink, err)
// after (retry transient errors before failing)
if gce.IsNotFound(err) {
return nil
}
if apiErr, ok := err.(*googleapi.Error); ok && (apiErr.Code == 429 || apiErr.Code >= 500) {
return fmt.Errorf("error deleting Subnetwork %s (transient, retry): %w", o.SelfLink, err)
}
return fmt.Errorf("error deleting Subnetwork %s: %w", o.SelfLink, err) Defensive patterns
Strategy: retry
Validate before calling
// before teardown, check subnet dependencies
for _, subnet := range []string{"mysubnet"} {
inUse, _ := subnetHasForwardingRules(project, region, subnet)
if inUse {
return fmt.Errorf("subnet %s still referenced; clean up first", subnet)
}
} Type guard
func isGoogleAPIError(err error) (*googleapi.Error, bool) {
ge, ok := err.(*googleapi.Error)
return ge, ok
} Try / catch
// treat NotFound as success, retry transient
call := func() error { return deleteSubnet(project, region, name) }
if err := retry.OnError(wait.Backoff{Steps: 5, Duration: time.Second}, isTransient, call); err != nil {
klog.Errorf("subnet delete failed permanently: %v", err)
} Prevention
- Ensure the deletion identity has compute.networkAdmin before running delete cluster.
- Delete load balancers/instances before the subnet.
- Re-run delete cluster after transient failures; it skips NotFound resources.
When it happens
Trigger: Calling kops delete cluster on GCE where the subnetwork delete API call fails with a non-404 error: e.g. the subnetwork is still in use by resources (forwarding rules, instances with alias IPs), permission denied on the compute service account, quota/billing issues, or transient Google API 5xx errors.
Common situations: Cluster deletion fails partway leaving orphaned resources that still reference the subnet; IAM roles for the deletion service account lack compute.subnetworks.delete; regional subnet still used by a lingering instance group or load balancer; API outage/rate limiting during teardown.
Related errors
- error deleting router %s: %v
- deleting forwardingRule %s: %w
- error finding CloudInstanceGroups: %v
- error listing routers: %v
- error deleting ServiceAccount %s: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/94657cb5b96c65b3.
Report an issue: GitHub.