{"record":{"id":"8581a6f5abe28381","repo":"kubernetes/kops","slug":"deleting-droplets-is-not-supported-yet","errorCode":null,"errorMessage":"deleting droplets is not supported yet","messagePattern":"deleting droplets is not supported yet","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/dotasks/droplet.go","lineNumber":149,"sourceCode":"\tuserData, err := fi.ResourceAsString(e.UserData)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar newDropletCount int\n\tif a == nil {\n\t\tnewDropletCount = e.Count\n\t} else {\n\n\t\texpectedCount := e.Count\n\t\tactualCount := a.Count\n\n\t\tif expectedCount == actualCount {\n\t\t\treturn nil\n\t\t}\n\n\t\tif actualCount > expectedCount {\n\t\t\treturn errors.New(\"deleting droplets is not supported yet\")\n\t\t}\n\n\t\tnewDropletCount = expectedCount - actualCount\n\t}\n\n\t// associate vpcuuid to the droplet if set.\n\tvpcUUID := \"\"\n\tif fi.ValueOf(e.NetworkCIDR) != \"\" {\n\t\ts, err := t.Cloud.GetVPCUUID(fi.ValueOf(e.NetworkCIDR), fi.ValueOf(e.VPCName))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"fetching vpcUUID from network cidr=%s: %w\", fi.ValueOf(e.NetworkCIDR), err)\n\t\t}\n\t\tvpcUUID = s\n\t} else if fi.ValueOf(e.VPCUUID) != \"\" {\n\t\tvpcUUID = fi.ValueOf(e.VPCUUID)\n\t}\n\n\tfor i := 0; i < newDropletCount; i++ {","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/dotasks/droplet.go#L131-L167","documentation":"Droplet RenderDO supports only scaling a droplet instance group up. Once actualCount exceeds expectedCount (i.e., a droplet needs to be deleted to converge), the task refuses since droplet-based (non-VMSS/autoscaled) scale-down is not implemented in kops.","triggerScenarios":"kops update cluster or rolling-update on DigitalOcean when a droplet instance group's instanceCount was lowered (or machines were removed from the spec) so existing droplets must be terminated.","commonSituations":"Reducing the size of a droplet instance group in the cluster spec; replacing droplets after a spec change; manually created extra droplets making actualCount > expectedCount during convergence.","solutions":["Manually delete the surplus droplets in the DigitalOcean console or via doctl compute droplet delete, then re-run kops update","Use a VMSS-style autoscaling group (DigitalOcean load-balancer backed group) instead of raw droplets for scalable groups","Increase expectedCount back to match reality if the shrink was unintentional","Implement scale-down in RenderDO (delete oldest droplets, then remove from LB) if maintaining a fork"],"exampleFix":"// before: shrink in spec triggers the error\ninstanceCount: 3 -> 2\n// after: delete the droplet manually first\ndoctl compute droplet delete <droplet-id>\n# then apply the new instanceCount","handlingStrategy":"validation","validationCode":"if desiredCount < actualCount && isDropletGroup {\n\treturn errors.New(\"scale-down of droplet groups unsupported; delete droplets manually first\")\n}","typeGuard":null,"tryCatchPattern":"if err := task.RenderDO(ctx, target, a, e); err != nil {\n\tif strings.Contains(err.Error(), \"deleting droplets is not supported yet\") {\n\t\t// delete surplus droplets via doctl/API, then re-run\n\t} else { return err }\n}","preventionTips":["Never shrink droplet instance groups via kops; remove droplets manually first","Keep expected and actual droplet counts in sync to avoid convergence attempts to delete","Use autoscaling group resources instead of raw droplets where scale-down is needed"],"tags":["digitalocean","droplet","scale-down","not-implemented"],"backgroundTag":"operation-not-supported","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"}