{"record":{"id":"8faa371f964d1d09","repo":"kubernetes/kops","slug":"error-deleting-warm-pool-w","errorCode":null,"errorMessage":"error deleting warm pool: %w","messagePattern":"error deleting warm pool: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/warmpool.go","lineNumber":149,"sourceCode":"\t\t\t\tMaxGroupPreparedCapacity: maxSize,\n\t\t\t\tMinSize:                  new(minSize),\n\t\t\t}\n\n\t\t\t_, err := svc.PutWarmPool(ctx, request)\n\t\t\tif err != nil {\n\t\t\t\tif awsup.AWSErrorCode(err) == \"ValidationError\" {\n\t\t\t\t\treturn fi.NewTryAgainLaterError(\"waiting for ASG to become ready\").WithError(err)\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"error modifying warm pool: %w\", err)\n\t\t\t}\n\t\t} else if a != nil {\n\t\t\t_, err := svc.DeleteWarmPool(ctx, &autoscaling.DeleteWarmPoolInput{\n\t\t\t\tAutoScalingGroupName: e.AutoscalingGroup.Name,\n\t\t\t\t// We don't need to do any cleanup so, the faster the better\n\t\t\t\tForceDelete: new(true),\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error deleting warm pool: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// For the terraform target, warmpool config is rendered inside the AutoscalingGroup resource\nfunc (_ *WarmPool) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *WarmPool) error {\n\treturn nil\n}\n","sourceCodeStart":131,"sourceCodeEnd":160,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/warmpool.go#L131-L160","documentation":"Wraps failures from autoscaling DeleteWarmPool during warm-pool RenderAWS when the warm pool must be removed (actual exists but expected is empty). ForceDelete=true is used, so most state errors are avoided; remaining errors are permissions or the ASG being concurrently mutated/deleted.","triggerScenarios":"RenderAWS takes the a != nil branch (warm pool exists, not desired anymore) and svc.DeleteWarmPool returns any SDK error.","commonSituations":"IAM missing autoscaling:DeleteWarmPool; two applies racing — another process deleted the ASG/warm pool first; region mismatch causing 'ASG not found' after a config change.","solutions":["Grant autoscaling:DeleteWarmPool in the IAM policy","Re-run kops update cluster — if the ASG/warm pool was already deleted, reconcile state (kops delete with --allow-deletes or re-create spec)","Verify the AutoScalingGroup name/region matches the task before retrying","Check the wrapped AWS error code; NotFound usually means state was already converged"],"exampleFix":"// before\nif err != nil {\n\treturn fmt.Errorf(\"error deleting warm pool: %w\", err)\n}\n// after\nif err != nil {\n\tif awsup.AWSErrorCode(err) == \"ValidationError\" { return fi.NewTryAgainLaterError(\"waiting for ASG\").WithError(err) }\n\treturn fmt.Errorf(\"error deleting warm pool: %w\", err)\n}","handlingStrategy":"retry","validationCode":"if !iamAllows(\"autoscaling:DeleteWarmPool\") { return errors.New(\"IAM policy missing autoscaling:DeleteWarmPool\") }\nout, _ := asg.DescribeWarmPool(&autoscaling.DescribeWarmPoolInput{AutoScalingGroupName: &asgName})\n_ = out // confirm warm pool still exists before delete","typeGuard":null,"tryCatchPattern":"_, err := svc.DeleteWarmPool(ctx, req)\nif err != nil {\n\tif code := awsup.AWSErrorCode(err); code == \"Throttling\" || code == \"ValidationError\" {\n\t\treturn fi.NewTryAgainLaterError(\"warm pool delete retried\").WithError(err)\n\t}\n\treturn err\n}","preventionTips":["Grant autoscaling:DeleteWarmPool to the kOps role","Avoid concurrent applies that race on the same ASG","Keep ForceDelete=true so instances in warm pool don't block deletion","Verify region/ASG name matches the kOps task"],"tags":["aws","autoscaling","warm-pool"],"backgroundTag":"aws-api-call-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"}