kubernetes/kops · error
failed to delete volume %s(%s): %w
Error message
failed to delete volume %s(%s): %w
What it means
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.
Source
Thrown at pkg/resources/hetzner/resources.go:310
}
_, errCh := actionClient.WatchProgress(ctx, result.Action)
if err := <-errCh; err != nil {
return err
}
return nil
}
func deleteVolume(cloud fi.Cloud, r *resources.Resource) error {
klog.Infof("Deleting Volume: %s(%s)", r.Name, r.ID)
c := cloud.(hetzner.HetznerCloud)
client := c.VolumeClient()
volume := r.Obj.(*hcloud.Volume)
_, err := client.Delete(context.TODO(), volume)
if err != nil {
return fmt.Errorf("failed to delete volume %s(%s): %w", r.Name, r.ID, err)
}
return nil
}
func dumpServer(op *resources.DumpOperation, r *resources.Resource) error {
server := r.Obj.(*hcloud.Server)
data := make(map[string]interface{})
data["id"] = r.ID
data["type"] = r.Type
data["raw"] = r.Obj
op.Dump.Resources = append(op.Dump.Resources, data)
i := &resources.Instance{
Name: r.ID,
}
if ip := server.PublicNet.IPv4.IP; ip != nil {View on GitHub (pinned to 4c8573c808)
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.
Example fix
// before: attached volume blocks delete
client.Delete(context.TODO(), volume) // volume is still attached to server X
// after: detach first
_, _, _ = actionClient.AttachVolume(ctx, server, hcloud.VolumeAttachOpts{Volume: volume}) // opposite op used at create
// at teardown ensure servers are deleted before volumes (kOps ordering already does this);
// for manual cleanup: hcloud volume detach <id> && kops delete cluster ... Defensive patterns
Strategy: try-catch
Validate before calling
vol, _, err := c.Volume.Get(ctx, strconv.Itoa(volumeID))
if err != nil { return err }
if vol == nil { return nil }
if vol.Server != nil {
return fmt.Errorf("volume %d still attached to server %d", volumeID, vol.Server.ID)
} Type guard
func isAttachedVolumeError(err error) bool {
var hErr hcloud.Error
return errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeVolumeAttached
} Try / catch
err := deleteVolume(...)
var hErr hcloud.Error
switch {
case err == nil:
return nil
case errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeNotFound:
return nil
case errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeVolumeAttached:
return detachVolumeThenRetry(err)
default:
return err
} Prevention
- 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.
When it happens
Trigger: client.Delete(ctx, volume) fails: volume attached to a server (hcloud conflict), invalid token, rate limit, or volume already deleted.
Common situations: Server crashed or was deleted out-of-band leaving attached volumes; PVC-backed volumes whose server teardown ordering raced; credential rotation mid-delete.
Related errors
- failed to delete network %s(%s): %w
- failed to delete firewall %s(%s): %w
- failed to delete load balancer %s(%s): %w
- failed to delete server %s(%s): %w
- error deleting Subnetwork %s: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/1e3584bef76a91b5.
Report an issue: GitHub.