{"record":{"id":"055907a8cc85efef","repo":"kubernetes/kops","slug":"failed-to-delete-instance-ip-s-w","errorCode":null,"errorMessage":"failed to delete instance IP %s: %w","messagePattern":"failed to delete instance IP (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/scaleway/resources.go","lineNumber":243,"sourceCode":"}\n\nfunc deleteServer(cloud fi.Cloud, tracker *resources.Resource) error {\n\tc := cloud.(scaleway.ScwCloud)\n\tserver := tracker.Obj.(*instance.Server)\n\n\treturn c.DeleteServer(server)\n}\n\nfunc deleteServerIP(cloud fi.Cloud, tracker *resources.Resource) error {\n\tc := cloud.(scaleway.ScwCloud)\n\tip := tracker.Obj.(*instance.IP)\n\n\terr := c.InstanceService().DeleteIP(&instance.DeleteIPRequest{\n\t\tZone: ip.Zone,\n\t\tIP:   ip.ID,\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete instance IP %s: %w\", ip.Address.String(), err)\n\t}\n\n\treturn nil\n}\n\nfunc deleteSSHKey(cloud fi.Cloud, tracker *resources.Resource) error {\n\tc := cloud.(scaleway.ScwCloud)\n\tsshkey := tracker.Obj.(*iam.SSHKey)\n\n\treturn c.DeleteSSHKey(sshkey)\n}\n\nfunc deleteVolume(cloud fi.Cloud, tracker *resources.Resource) error {\n\tc := cloud.(scaleway.ScwCloud)\n\tvolume := tracker.Obj.(*instance.Volume)\n\n\treturn c.DeleteVolume(volume)\n}","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/scaleway/resources.go#L225-L261","documentation":"deleteServerIP removes a single Scaleway flexible IP tracked for cluster deletion. If the InstanceService DeleteIP call fails, the error is wrapped with the IP address for identification. This occurs per-resource during the delete loop and contributes to no-progress/timeout failures if persistent.","triggerScenarios":"DeleteResources invokes deleteServerIP (pkg/resources/scaleway/resources.go:243) and Instance API DeleteIP fails: IP already deleted (404), credentials lack permission, wrong zone in the tracked IP, or API throttling/transient errors.","commonSituations":"A concurrent deletion already removed the IP (404 on retry); IAM policy on the Scaleway project denies instance:DeleteIP; zone drift between listing and deletion; Scaleway rate limits during mass deletion of a large cluster.","solutions":["Re-run the delete — if the IP was already deleted (404), a fresh ListResources pass will drop it from the set","Verify the Scaleway credentials include permission to delete IPs (instance:* on the project)","Check the IP still exists with `scw instance ip list` and delete it manually if the API keeps failing","Retry with backoff if the error is 429/5xx throttling during bulk deletion"],"exampleFix":"// before\nscw instance ip delete ip-id=<id> # fails: permissions\n// after: grant instance delete scope to the credential, then\nkops delete cluster --name mycluster --yes","handlingStrategy":"retry","validationCode":"// Confirm the IP still exists before deleting to avoid 404s\n_, err := c.InstanceService().GetIP(&instance.GetIPRequest{Zone: ip.Zone, IP: ip.ID})\nif err != nil && scw.IsNotFoundError(err) {\n    return nil // already deleted\n}","typeGuard":null,"tryCatchPattern":"if err := deleteServerIP(cloud, tracker); err != nil {\n    var apiErr *scw.Error\n    if errors.As(err, &apiErr) && apiErr.StatusCode == http.StatusNotFound {\n        return nil // already gone — treat as success\n    }\n    return backoffRetry(err)\n}","preventionTips":["Treat 404 as success in idempotent delete flows","Ensure credentials have instance delete scopes","Add backoff for 429/5xx during bulk deletes","Re-run ListResources before retrying deletes to refresh the resource set"],"tags":["scaleway","delete","api-error","permissions"],"backgroundTag":"cloud-resource-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"}