{"record":{"id":"4f97b260d7fe9296","repo":"kubernetes/kops","slug":"error-deleting-instance-q-v-4f97b2","errorCode":null,"errorMessage":"error deleting instance %q: %v","messagePattern":"error deleting instance %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awsup/aws_cloud.go","lineNumber":505,"sourceCode":"\n\treturn nil\n}\n\nfunc deleteInstance(ctx context.Context, c AWSCloud, i *cloudinstances.CloudInstance) error {\n\tid := i.ID\n\tif id == \"\" {\n\t\treturn fmt.Errorf(\"id was not set on CloudInstance: %v\", i)\n\t}\n\n\trequest := &ec2.TerminateInstancesInput{\n\t\tInstanceIds: []string{id},\n\t}\n\n\tif _, err := c.EC2().TerminateInstances(ctx, request); err != nil {\n\t\tif AWSErrorCode(err) == \"InvalidInstanceID.NotFound\" {\n\t\t\tklog.V(2).Infof(\"Got InvalidInstanceID.NotFound error deleting instance %q; will treat as already-deleted\", id)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"error deleting instance %q: %v\", id, err)\n\t\t}\n\t}\n\n\tklog.V(8).Infof(\"deleted aws ec2 instance %q\", id)\n\n\treturn nil\n}\n\n// deregisterInstance ensures that the instance is fully drained/removed from all associated loadBalancers and targetGroups before termination.\nfunc deregisterInstance(ctx context.Context, c AWSCloud, i *cloudinstances.CloudInstance) error {\n\tasg := i.CloudInstanceGroup.Raw.(*autoscalingtypes.AutoScalingGroup)\n\n\tasgDetails, err := c.Autoscaling().DescribeAutoScalingGroups(ctx, &autoscaling.DescribeAutoScalingGroupsInput{\n\t\tAutoScalingGroupNames: []string{aws.ToString(asg.AutoScalingGroupName)},\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error describing autoScalingGroups: %v\", err)\n\t}","sourceCodeStart":487,"sourceCodeEnd":523,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awsup/aws_cloud.go#L487-L523","documentation":"The ec2.TerminateInstances call failed with an error other than InvalidInstanceID.NotFound (which kOps deliberately treats as already-deleted success). This means the instance could not be terminated for a real reason — permissions, invalid state, dependency, or API/network failure — and kOps surfaces the raw AWS error wrapped with the instance ID.","triggerScenarios":"AWSCloud.deleteInstance calls c.EC2().TerminateInstances and AWS returns e.g. AccessDenied, InvalidInstanceID.Malformed, OperationNotPermitted (instance protected against termination / attached EBS volume with termination protection), or a throttling/network error.","commonSituations":"IAM role missing ec2:TerminateInstances; instance has termination protection or is part of an ASG with instance protection; spot instance interruption conflicts; wrong region/credentials; malformed instance ID passed in.","solutions":["Read the wrapped AWS error code and address it directly (AccessDenied → fix IAM; OperationNotPermitted → disable termination protection / scale-down protection)","Ensure the IAM role used by kOps has ec2:TerminateInstances on the relevant instances","Check for ASG instance protection or scale-in protection on the instance and remove it","If throttling/transient, retry; InvalidInstanceID.NotFound is already treated as success"],"exampleFix":"// before: instance protected\n// error deleting instance \"i-0abc...\": OperationNotPermitted: The instance 'i-0abc' may not be terminated...\n// after: disable protection then retry\naws autoscaling set-instance-protection --instance-ids i-0abc... --auto-scaling-group-name nodes --no-protected-from-scale-in\naws ec2 modify-instance-attribute --instance-id i-0abc... --no-disable-api-termination","handlingStrategy":"try-catch","validationCode":"// pre-check termination protection and ASG scale-in protection\nout, _ := svc.DescribeInstanceAttribute(&ec2.DescribeInstanceAttributeInput{\n\tInstanceId: aws.String(inst.ID), Attribute: aws.String(\"disableApiTermination\")})\nif aws.ToBool(out.DisableApiTermination.Value) {\n\treturn fmt.Errorf(\"instance %s has API termination enabled-protection; disable first\", inst.ID)\n}","typeGuard":"func isAlreadyDeleted(err error) bool {\n\tvar ae smithy.APIError\n\treturn errors.As(err, &ae) && ae.ErrorCode() == \"InvalidInstanceID.NotFound\"\n}","tryCatchPattern":"if err := cloud.DeleteInstance(inst); err != nil {\n\tvar ae smithy.APIError\n\tif errors.As(err, &ae) {\n\t\tswitch ae.ErrorCode() {\n\t\tcase \"OperationNotPermitted\":\n\t\t\t// disable termination/scale-in protection then retry\n\t\tcase \"AccessDenied\":\n\t\t\t// fix IAM ec2:TerminateInstances\n\t\t}\n\t}\n\treturn err\n}","preventionTips":["Grant ec2:TerminateInstances to the kOps IAM role","Disable ASG scale-in protection / instance termination protection before deleting","Confirm region and credentials match the cluster","Treat InvalidInstanceID.NotFound as success (kOps already does)"],"tags":["aws","ec2","instance-termination","permissions"],"backgroundTag":"ec2-terminate-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"}