{"record":{"id":"c9577325d4802b58","repo":"kubernetes/kops","slug":"error-listing-managed-instances-for-q-v","errorCode":null,"errorMessage":"error listing managed instances for %q: %v","messagePattern":"error listing managed instances for %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gce/instancegroups.go","lineNumber":62,"sourceCode":"// DeleteCloudInstanceGroup deletes the InstanceGroupManager and current InstanceTemplate\nfunc DeleteCloudInstanceGroup(c GCECloud, g *cloudinstances.CloudInstanceGroup) error {\n\tmig := g.Raw.(*compute.InstanceGroupManager)\n\terr := DeleteMIGInstances(c, mig)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttimeout := time.Now().Add(10 * time.Minute)\n\n\tklog.Infof(\"Waiting for instances in MIG %q to terminate...\", mig.Name)\n\tfor {\n\t\tif time.Now().After(timeout) {\n\t\t\treturn fmt.Errorf(\"timed out waiting for instances in MIG %q to terminate\", mig.Name)\n\t\t}\n\n\t\tinstances, err := ListManagedInstances(c, mig)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error listing managed instances for %q: %v\", mig.Name, err)\n\t\t}\n\t\tif len(instances) == 0 {\n\t\t\tklog.Infof(\"All instances in MIG %q terminated\", mig.Name)\n\t\t\tbreak\n\t\t}\n\t\tklog.Infof(\"%d instance(s) remaining in MIG %q, waiting...\", len(instances), mig.Name)\n\t\ttime.Sleep(PollingInterval)\n\t}\n\n\terr = DeleteInstanceGroupManager(c, mig)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn DeleteInstanceTemplate(c, mig.InstanceTemplate)\n}\n\n// DeleteInstance deletes a GCE instance","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gce/instancegroups.go#L44-L80","documentation":"Inside DeleteCloudInstanceGroup's polling loop, each iteration calls ListManagedInstances to check remaining VMs in the MIG. If that list call fails, the error is wrapped with the MIG name and returned immediately, aborting the delete instead of continuing to wait.","triggerScenarios":"ListManagedInstances (compute.InstanceGroupManagers.ListInstances) returning a non-nil error during the delete loop — transient API errors (5xx, rate limiting/quota), permission denied on the compute API, invalid MIG name/zone, or the MIG being deleted concurrently so the endpoint 404s mid-loop.","commonSituations":"kops delete cluster / delete instancegroup on GCE hitting API rate limits with many MIGs, a service account missing compute.viewer rights, regional/zone mismatch, or a concurrently deleted MIG.","solutions":["Inspect the wrapped inner error (`%v`) for the root cause: 403/permission → grant compute API roles to the service account; 404 → the MIG is already gone, safe to proceed.","For rate limiting (429/403 quota), retry with backoff or reduce concurrent deletions.","Verify the MIG's zone/name are correct and the Compute Engine API is enabled for the project.","Re-run `kops delete` after the transient API failure clears."],"exampleFix":"// before: list fails on 404 (MIG already deleted) and aborts\ninstances, err := ListManagedInstances(c, mig)\n// after (caller-level): treat already-deleted MIG as success\nif strings.Contains(err.Error(), \"notFound\") {\n    return nil // MIG already deleted\n}","handlingStrategy":"retry","validationCode":"// confirm API access before starting deletion loops\n_, err := svc.InstanceGroupManagers.List(project, zone).MaxResults(1).Context(ctx).Do()\nif err != nil {\n\treturn fmt.Errorf(\"compute API unreachable or unauthorized: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := cloud.DeleteCloudInstanceGroup(mig)\nif err != nil && strings.Contains(err.Error(), \"error listing managed instances\") {\n\tvar gerr *googleapi.Error\n\tif errors.As(err, &gerr) {\n\t\tswitch gerr.Code {\n\t\tcase http.StatusNotFound:\n\t\t\treturn nil // already deleted\n\t\tcase http.StatusForbidden:\n\t\t\treturn fmt.Errorf(\"missing compute API permissions: %w\", err)\n\t\tdefault:\n\t\t\treturn retryWithBackoff(err)\n\t\t}\n\t}\n}","preventionTips":["Grant the service account compute.viewer/compute.admin roles before teardown operations.","Apply backoff/jitter when deleting many MIGs concurrently to avoid quota errors.","Enable the Compute Engine API in the target project before running kops delete."],"tags":["gce","instance-groups","api-error","mig"],"backgroundTag":"api-list-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}