{"record":{"id":"1e3584bef76a91b5","repo":"kubernetes/kops","slug":"failed-to-delete-volume-s-s-w","errorCode":null,"errorMessage":"failed to delete volume %s(%s): %w","messagePattern":"failed to delete volume (.+?)\\((.+?)\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/hetzner/resources.go","lineNumber":310,"sourceCode":"\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 {\n\t\treturn fmt.Errorf(\"failed to delete volume %s(%s): %w\", r.Name, r.ID, err)\n\t}\n\n\treturn nil\n}\n\nfunc dumpServer(op *resources.DumpOperation, r *resources.Resource) error {\n\tserver := r.Obj.(*hcloud.Server)\n\n\tdata := make(map[string]interface{})\n\tdata[\"id\"] = r.ID\n\tdata[\"type\"] = r.Type\n\tdata[\"raw\"] = r.Obj\n\top.Dump.Resources = append(op.Dump.Resources, data)\n\n\ti := &resources.Instance{\n\t\tName: r.ID,\n\t}\n\tif ip := server.PublicNet.IPv4.IP; ip != nil {","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/hetzner/resources.go#L292-L328","documentation":"Wrapped error from deleteVolume: hcloud VolumeClient.Delete failed while kOps removes a cluster volume. Commonly the underlying error is hcloud's 'volume is still attached' conflict, since volumes must be detached (or their server deleted) first.","triggerScenarios":"client.Delete(ctx, volume) fails: volume attached to a server (hcloud conflict), invalid token, rate limit, or volume already deleted.","commonSituations":"Server crashed or was deleted out-of-band leaving attached volumes; PVC-backed volumes whose server teardown ordering raced; credential rotation mid-delete.","solutions":["Detach the volume from its server (console: `hcloud volume detach`) or delete the attached server, then retry.","Verify HCLOUD_TOKEN validity and write scope.","If not-found, the volume is already gone — rerun delete.","Retry after any rate-limit window indicated by the wrapped error."],"exampleFix":"// before: attached volume blocks delete\nclient.Delete(context.TODO(), volume) // volume is still attached to server X\n// after: detach first\n_, _, _ = actionClient.AttachVolume(ctx, server, hcloud.VolumeAttachOpts{Volume: volume}) // opposite op used at create\n// at teardown ensure servers are deleted before volumes (kOps ordering already does this);\n// for manual cleanup: hcloud volume detach <id> && kops delete cluster ...","handlingStrategy":"try-catch","validationCode":"vol, _, err := c.Volume.Get(ctx, strconv.Itoa(volumeID))\nif err != nil { return err }\nif vol == nil { return nil }\nif vol.Server != nil {\n    return fmt.Errorf(\"volume %d still attached to server %d\", volumeID, vol.Server.ID)\n}","typeGuard":"func isAttachedVolumeError(err error) bool {\n    var hErr hcloud.Error\n    return errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeVolumeAttached\n}","tryCatchPattern":"err := deleteVolume(...)\nvar hErr hcloud.Error\nswitch {\ncase err == nil:\n    return nil\ncase errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeNotFound:\n    return nil\ncase errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeVolumeAttached:\n    return detachVolumeThenRetry(err)\ndefault:\n    return err\n}","preventionTips":["Always delete servers before volumes (kOps resource ordering handles this; preserve it).","Detach orphaned volumes in the console before `kops delete cluster` if servers were removed manually.","Check `hcloud volume describe` for the attached server prior to deletion.","Keep the API token valid across the whole teardown."],"tags":["hetzner","volume","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-12T12:17:11.808Z"}