{"record":{"id":"9b9190fdb61cb476","repo":"kubernetes/kops","slug":"found-multiple-kops-natgateways-in-route-table-s","errorCode":null,"errorMessage":"found multiple kOps NatGateways in route table %s","messagePattern":"found multiple kOps NatGateways in route table (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/natgateway.go","lineNumber":245,"sourceCode":"\t\t\t\tclusterName, ok := routeTable.Tags[awsup.TagClusterName]\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, fmt.Errorf(\"Could not find '%s' tag from route table\", awsup.TagClusterName)\n\t\t\t\t}\n\t\t\t\tfilteredNatGateways := []*ec2types.NatGateway{}\n\t\t\t\tfor _, natGatewayID := range natGatewayIDs {\n\t\t\t\t\tgw, err := findNatGatewayById(ctx, cloud, fi.ValueOf(natGatewayID))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\n\t\t\t\t\tif raws.HasOwnedTag(string(ec2types.ResourceTypeNatgateway)+\":\"+fi.ValueOf(natGatewayID), gw.Tags, clusterName) {\n\t\t\t\t\t\tfilteredNatGateways = append(filteredNatGateways, gw)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif len(filteredNatGateways) == 0 {\n\t\t\t\t\tklog.V(2).Infof(\"no kOps NatGateway found in route table %s\", *rt.RouteTableId)\n\t\t\t\t} else if len(filteredNatGateways) > 1 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"found multiple kOps NatGateways in route table %s\", *rt.RouteTableId)\n\t\t\t\t} else {\n\t\t\t\t\treturn filteredNatGateways[0], nil\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn findNatGatewayById(ctx, cloud, fi.ValueOf(natGatewayIDs[0]))\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil, nil\n}\n\nfunc (s *NatGateway) CheckChanges(a, e, changes *NatGateway) error {\n\t// New\n\tif a == nil {\n\t\tif !fi.ValueOf(e.Shared) {\n\t\t\tif e.ElasticIP == nil {\n\t\t\t\treturn fi.RequiredField(\"ElasticIP\")","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/natgateway.go#L227-L263","documentation":"After filtering the route table's multiple NAT gateways by cluster tag, more than one gateway remained tagged as belonging to this cluster. kOps cannot decide which one the route should point to and fails the lookup.","triggerScenarios":"len(filteredNatGateways) > 1 — the route table has multiple nat- routes AND findNatGatewayById confirms each is a live, cluster-tagged (KubernetesCluster == this cluster) NAT gateway.","commonSituations":"A previous kops run left an orphaned NAT gateway still tagged for the cluster while a new one was also created; concurrent/overlapping `kops update cluster` runs; manual NAT gateway creation cloned tags from the original.","solutions":["Delete the orphaned/extra NAT gateway: `aws ec2 delete-nat-gateway --nat-gateway-id nat-EXTRA` (keep the one the active route uses)","Remove the stale cluster tag from the gateway you intend to retire so filtering yields one","Prevent concurrent kops update runs on the same cluster (CI locking / single operator)","Re-run `kops update cluster --yes` after cleanup so routes converge to the single remaining gateway"],"exampleFix":"// before: two cluster-tagged NAT gateways on the route table\naws ec2 describe-nat-gateways --filter Name=tag:KubernetesCluster,Values=mycluster\n// after: delete the orphan\naws ec2 delete-nat-gateway --nat-gateway-id nat-ORPHAN","handlingStrategy":"validation","validationCode":"out, _ := ec2Client.DescribeNatGateways(ctx, &ec2.DescribeNatGatewaysInput{\n  Filter: []ec2types.Filter{{Name: aws.String(\"tag:KubernetesCluster\"), Values: []string{clusterName}}}})\nif len(out.NatGateways) > 1 { fmt.Println(\"multiple cluster NAT gateways — delete orphans before kops update\") }","typeGuard":"func singleClusterGateway(gws []ec2types.NatGateway) *ec2types.NatGateway {\n  if len(gws) == 1 { return &gws[0] }\n  return nil\n}","tryCatchPattern":"ngw, err := findNatGatewayFromRouteTable(ctx, cloud, rt)\nif err != nil && strings.Contains(err.Error(), \"found multiple kOps NatGateways\") {\n  // enumerate gateways, delete the orphan, retry update\n}","preventionTips":["Delete orphaned NAT gateways after failed/aborted kops runs","Never run concurrent `kops update cluster` on one cluster (use CI locking)","Don't clone existing NAT gateways with their tags in shared VPCs"],"tags":["aws","ec2","natgateway","routetable","duplicate-resources"],"backgroundTag":"ambiguous-tag-lookup","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"}