{"record":{"id":"ecfbda8b878a3615","repo":"kubernetes/kops","slug":"failed-to-delete-server-s-s-w","errorCode":null,"errorMessage":"failed to delete server %s(%s): %w","messagePattern":"failed to delete server (.+?)\\((.+?)\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/hetzner/resources.go","lineNumber":291,"sourceCode":"\t\treturn fmt.Errorf(\"failed to delete load balancer %s(%s): %w\", r.Name, r.ID, err)\n\t}\n\n\treturn nil\n}\n\nfunc deleteServer(cloud fi.Cloud, r *resources.Resource) error {\n\tctx := context.TODO()\n\n\tklog.Infof(\"Deleting Server: %s(%s)\", r.Name, r.ID)\n\n\tc := cloud.(hetzner.HetznerCloud)\n\tserverClient := c.ServerClient()\n\tactionClient := c.ActionClient()\n\n\tserver := r.Obj.(*hcloud.Server)\n\tresult, _, err := serverClient.DeleteWithResult(ctx, server)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete server %s(%s): %w\", r.Name, r.ID, err)\n\t}\n\n\t_, errCh := actionClient.WatchProgress(ctx, result.Action)\n\tif err := <-errCh; err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc deleteVolume(cloud fi.Cloud, r *resources.Resource) error {\n\tklog.Infof(\"Deleting Volume: %s(%s)\", r.Name, r.ID)\n\n\tc := cloud.(hetzner.HetznerCloud)\n\tclient := c.VolumeClient()\n\tvolume := r.Obj.(*hcloud.Volume)\n\t_, err := client.Delete(context.TODO(), volume)\n\tif err != nil {","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/hetzner/resources.go#L273-L309","documentation":"Wrapped error from deleteServer: the hcloud ServerClient.DeleteWithResult call failed when kOps deletes a cluster server. Unlike simple deletes, this uses DeleteWithResult and then watches the action via WatchProgress; this specific message only covers the initial DeleteWithResult failure, while a failed action watch surfaces as the raw error from errCh.","triggerScenarios":"serverClient.DeleteWithResult(ctx, server) returns an error: server already stopped/deleted (not-found), API token invalid, rate limit, or server locked (e.g. rescue/backup in progress).","commonSituations":"Server was terminated manually in the Hetzner console before kOps delete; Hetzner maintenance/lock on the server; token permissions lacking server write scope.","solutions":["Inspect the wrapped hcloud error; if it is not-found, the server is already gone and the cluster delete can be retried.","Confirm the API token has server write permissions and is not expired.","Wait for any running server operations (backups, rescues) to finish — locked servers cannot be deleted.","If the initial delete succeeds but WatchProgress errors, rerun the delete; kOps refreshes server state each pass."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"srv, _, err := c.Server.Get(ctx, strconv.Itoa(serverID))\nif err != nil { return err }\nif srv == nil { return nil } // already deleted\nif srv.Status == hcloud.ServerStatusStarting || srv.Locked() { // locked servers can't be deleted\n    return fmt.Errorf(\"server %d is busy/locked (status=%s)\", serverID, srv.Status)\n}","typeGuard":"func isHcloudErrorWithCode(err error, code hcloud.ErrorCode) bool {\n    var hErr hcloud.Error\n    return errors.As(err, &hErr) && hErr.Code == code\n}","tryCatchPattern":"_, _, err := serverClient.DeleteWithResult(ctx, server)\nif err != nil {\n    var hErr hcloud.Error\n    if errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeNotFound {\n        return nil // already gone\n    }\n    if errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeRateLimitExceeded {\n        return backoffRetry(err)\n    }\n    return fmt.Errorf(\"failed to delete server %s(%s): %w\", name, id, err)\n}","preventionTips":["Do not delete servers from the Hetzner console while kOps delete is running.","Ensure no rescue mode, backups or other locks are active on servers before teardown.","Use a token with server write scope.","Rerun the delete if WatchProgress reports an error — server state is refreshed each pass."],"tags":["hetzner","server","deletion","cloud-api"],"backgroundTag":"hcloud-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"}