{"record":{"id":"66d61d5a100d6f07","repo":"kubernetes/kops","slug":"error-deleting-instance-s-w","errorCode":null,"errorMessage":"error deleting Instance %s: %w","messagePattern":"error deleting Instance (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gce/wrappers.go","lineNumber":101,"sourceCode":"\n\treturn c.WaitForOp(op)\n}\n\n// DeleteInstance deletes the specified instance (by URL) in GCE\nfunc DeleteInstance(c GCECloud, instanceSelfLink string) error {\n\tklog.V(2).Infof(\"Deleting GCE Instance %s\", instanceSelfLink)\n\tu, err := ParseGoogleCloudURL(instanceSelfLink)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\top, err := c.Compute().Instances().Delete(u.Project, u.Zone, u.Name)\n\tif err != nil {\n\t\tif IsNotFound(err) {\n\t\t\tklog.Infof(\"Instance not found, assuming deleted: %q\", instanceSelfLink)\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"error deleting Instance %s: %w\", instanceSelfLink, err)\n\t}\n\n\treturn c.WaitForOp(op)\n}\n\n// ListManagedInstances lists the specified InstanceGroupManagers in GCE\nfunc ListManagedInstances(c GCECloud, igm *compute.InstanceGroupManager) ([]*compute.ManagedInstance, error) {\n\tctx := context.Background()\n\tproject := c.Project()\n\n\tzoneName := LastComponent(igm.Zone)\n\n\t// TODO: Only select a subset of fields\n\t//\treq.Fields(\n\t//\t\tgoogleapi.Field(\"items/selfLink\"),\n\t//\t\tgoogleapi.Field(\"items/metadata/items[key='cluster-name']\"),\n\t//\t\tgoogleapi.Field(\"items/metadata/items[key='instance-template']\"),\n\t//\t)","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gce/wrappers.go#L83-L119","documentation":"This error is returned by DeleteInstance when Instances().Delete(project, zone, name) fails with anything other than 404 Not Found. It wraps the googleapi error with the instance's selfLink. Not-found instances are treated as already deleted and return nil, so this error signals a real API failure: permissions, dependency (e.g. instance protected by deletion protection or still attached), or a transient API problem.","triggerScenarios":"Calling DeleteInstance for a remaining GCE VM (orphaned instances after MIG teardown) where Instances().Delete returns a non-NotFound error: deletion protection enabled, instance already being deleted by another operation (conflict), IAM denial, wrong zone/project parsed from the selfLink, or API 5xx.","commonSituations":"Instances with deletionProtection=true left from custom provisioning; two teardown processes deleting the same instance concurrently causing OPERATION_NOT_DONE/409 conflicts; stale selfLinks after instances were rebuilt; service account lacking compute.instances.delete; zone misconfiguration causing 404-style failures surfaced as other errors.","solutions":["Check the wrapped googleapi error code: 409/operation-in-progress means retry once the concurrent operation completes","Disable deletion protection (`gcloud compute instances update NAME --no-deletion-protection`) if that flag is set","Confirm the selfLink parses to the right project/zone and the instance still exists with `gcloud compute instances describe`","Verify IAM (compute.instances.delete / compute.instanceAdmin.v1) for the service account","Retry — kOps treats 404 as success, so re-running the delete is safe and idempotent"],"exampleFix":"// before: single-shot delete, fails on protection flag\nif err := DeleteInstance(cloud, instSelfLink); err != nil {\n\treturn err\n}\n// after: clear deletion protection, then retry delete\nif err := DeleteInstance(cloud, instSelfLink); err != nil {\n\tif strings.Contains(err.Error(), \"deletionProtection\") {\n\t\tif _, e := cloud.Compute().Instances().SetDeletionProtection(proj, zone, name, false); e != nil {\n\t\t\treturn e\n\t\t}\n\t\treturn DeleteInstance(cloud, instSelfLink)\n\t}\n\treturn err\n}","handlingStrategy":"try-catch","validationCode":"// Confirm the instance exists and lacks deletion protection before deleting\ninst, err := cloud.Compute().Instances().Get(project, zone, name)\nif err != nil {\n\tif isNotFound(err) {\n\t\treturn nil\n\t}\n\treturn err\n}\nif inst.DeletionProtection {\n\tif _, err := cloud.Compute().Instances().SetDeletionProtection(project, zone, name, false); err != nil {\n\t\treturn err\n\t}\n}","typeGuard":"func isDeletionConflict(err error) bool {\n\tvar gerr *googleapi.Error\n\treturn errors.As(err, &gerr) && (gerr.Code == 409 || gerr.Code == 412)\n}","tryCatchPattern":"err := gce.DeleteInstance(cloud, selfLink)\nif err != nil {\n\tvar gerr *googleapi.Error\n\tif errors.As(err, &gerr) {\n\t\tswitch gerr.Code {\n\t\tcase 404:\n\t\t\treturn nil // already deleted\n\t\tcase 409, 412:\n\t\t\t// concurrent operation; retry after backoff\n\t\tcase 403:\n\t\t\t// check IAM and deletion protection\n\t\t}\n\t}\n\treturn err\n}","preventionTips":["Avoid setting deletionProtection on kOps-managed instances","Run teardown serially per instance to avoid 409 conflicts with in-flight deletes","Validate selfLinks parse to the expected project/zone before deleting","Grant compute.instanceAdmin.v1 to the operator service account"],"tags":["gce","compute-api","instance","deletion","wrapped-error"],"backgroundTag":"gce-api-delete-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"}