{"record":{"id":"06da9832eb3fa57b","repo":"kubernetes/kops","slug":"error-deleting-ngw-q-v","errorCode":null,"errorMessage":"error deleting ngw %q: %v","messagePattern":"error deleting ngw %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/aws/aws.go","lineNumber":1766,"sourceCode":"\treturn nil\n}\n\nfunc DeleteNatGateway(cloud fi.Cloud, t *resources.Resource) error {\n\tctx := context.TODO()\n\tc := cloud.(awsup.AWSCloud)\n\n\tid := t.ID\n\n\tklog.V(2).Infof(\"Removing NatGateway %s\", t.Name)\n\trequest := &ec2.DeleteNatGatewayInput{\n\t\tNatGatewayId: &id,\n\t}\n\t_, err := c.EC2().DeleteNatGateway(ctx, request)\n\tif err != nil {\n\t\tif IsDependencyViolation(err) {\n\t\t\treturn err\n\t\t}\n\t\treturn fmt.Errorf(\"error deleting ngw %q: %v\", t.Name, err)\n\t}\n\treturn nil\n}\n\nfunc deleteRoute53Records(ctx context.Context, cloud fi.Cloud, zone route53types.HostedZone, resourceTrackers []*resources.Resource) error {\n\tc := cloud.(awsup.AWSCloud)\n\n\tvar changes []route53types.Change\n\tvar names []string\n\tfor _, resourceTracker := range resourceTrackers {\n\t\tnames = append(names, resourceTracker.Name)\n\t\tchanges = append(changes, route53types.Change{\n\t\t\tAction:            route53types.ChangeActionDelete,\n\t\t\tResourceRecordSet: resourceTracker.Obj.(*route53types.ResourceRecordSet),\n\t\t})\n\t}\n\thuman := strings.Join(names, \", \")\n\tklog.V(2).Infof(\"Deleting route53 records %q\", human)","sourceCodeStart":1748,"sourceCodeEnd":1784,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/aws/aws.go#L1748-L1784","documentation":"DeleteNatGateway wraps a failed EC2 DeleteNatGateway call with the resource name. Dependency violations are returned unwrapped so the resource tracker can retry after dependents (like the EIP) are gone; all other AWS errors surface here.","triggerScenarios":"DeleteNatGateway fails with AccessDenied (missing ec2:DeleteNatGateway), InvalidNatGatewayID.NotFound (already deleted externally), throttling, or a transient 5xx during cluster teardown.","commonSituations":"NAT gateway already deleted manually or by another tool while kOps lists-then-deletes; IAM policy gaps; throttling in accounts with many NAT gateways across AZs.","solutions":["Retry the deletion; NAT gateway deletion is asynchronous so a subsequent pass usually succeeds.","Confirm with aws ec2 describe-nat-gateways whether it is already deleted/deleting.","Grant ec2:DeleteNatGateway in the caller's IAM policy.","Check the wrapped error detail for throttling and add backoff/concurrency limits.","Verify the NAT gateway ID/region is correct if AuthFailure or NotFound persists."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"ngws, err := c.EC2().DescribeNatGateways(ctx, &ec2.DescribeNatGatewaysInput{NatGatewayIds: []string{*t.ID}})\nif err != nil || len(ngws.NatGateways) == 0 || ngws.NatGateways[0].State == \"deleted\" { /* skip */ }","typeGuard":null,"tryCatchPattern":"err := DeleteNatGateway(cloud, r)\nif err != nil {\n    if awsup.AWSErrorCode(err) == \"InvalidNatGatewayID.NotFound\" { return nil }\n    return err // transient errors retried on next reconciliation pass\n}","preventionTips":["Retry passes — NAT gateway deletion is async and may show 'deleting' for a while.","Grant ec2:DeleteNatGateway in IAM.","Release the associated EIP handling per AWS guidance to avoid dependency issues.","Confirm ID/region if NotFound persists unexpectedly.","Avoid duplicate delete jobs from multiple operators."],"tags":["aws","ec2","nat-gateway","deletion"],"backgroundTag":"aws-api-delete-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"}