{"record":{"id":"a8dbc13df28c368b","repo":"kubernetes/kops","slug":"error-listing-nat-gateways-v","errorCode":null,"errorMessage":"error listing Nat Gateways %v","messagePattern":"error listing Nat Gateways (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/natgateway.go","lineNumber":79,"sourceCode":"}\n\nfunc (e *NatGateway) Find(c *fi.CloudupContext) (*NatGateway, error) {\n\tctx := c.Context()\n\tcloud := awsup.GetCloud(c)\n\tvar ngw *ec2types.NatGateway\n\tactual := &NatGateway{}\n\n\tif fi.ValueOf(e.ID) != \"\" {\n\t\t// We have an existing NGW, lets look up the EIP\n\t\tngwIds := []string{fi.ValueOf(e.ID)}\n\n\t\trequest := &ec2.DescribeNatGatewaysInput{\n\t\t\tNatGatewayIds: ngwIds,\n\t\t}\n\n\t\tresponse, err := cloud.EC2().DescribeNatGateways(ctx, request)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error listing Nat Gateways %v\", err)\n\t\t}\n\n\t\tif len(response.NatGateways) != 1 {\n\t\t\treturn nil, fmt.Errorf(\"found %d Nat Gateways with ID %q, expected 1\", len(response.NatGateways), fi.ValueOf(e.ID))\n\t\t}\n\t\tngw = &response.NatGateways[0]\n\n\t\tif len(ngw.NatGatewayAddresses) != 1 {\n\t\t\treturn nil, fmt.Errorf(\"found %d EIP Addresses for 1 NATGateway, expected 1\", len(ngw.NatGatewayAddresses))\n\t\t}\n\t} else {\n\t\t// This is the normal/default path\n\t\tvar err error\n\t\tngw, err = e.findNatGateway(c)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif ngw == nil {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/natgateway.go#L61-L97","documentation":"natgateway.go Find() fetches a NAT gateway by its explicit ID via ec2:DescribeNatGateways and wraps any API error with this message. It is thrown only when e.ID is set and the DescribeNatGateways call fails, so the task's actual state cannot be determined.","triggerScenarios":"DescribeNatGateways with NatGatewayIds=[e.ID] errors: AccessDenied on ec2:DescribeNatGateways, throttling, invalid NAT gateway ID format, or network failure.","commonSituations":"State store references a NAT gateway from another region/account; IAM policy missing describe permission; transient AWS throttling in CI loops.","solutions":["Check the wrapped error code to distinguish auth vs throttling vs invalid-ID","Verify the NAT gateway ID in the kOps state exists in the configured region/account (aws ec2 describe-nat-gateways --nat-gateway-ids ngw-...)","Grant ec2:DescribeNatGateways to the kOps IAM role","Retry on throttling","If the NAT gateway was deleted out-of-band, clear the ID from state (kops edit cluster / replace the task) so it can be recreated"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"_, err := cloud.EC2().DescribeNatGateways(ctx, &ec2.DescribeNatGatewaysInput{NatGatewayIds: []string{id}})\nif err != nil { /* verify ID/region/permissions before the real operation */ }","typeGuard":null,"tryCatchPattern":"response, err := cloud.EC2().DescribeNatGateways(ctx, request)\nif err != nil {\n  var re *awshttp.ResponseError\n  if errors.As(err, &re) && isThrottling(re) { backoff(); continue }\n  return nil, fmt.Errorf(\"error listing Nat Gateways %w\", err)\n}","preventionTips":["Keep state store and AWS region in sync","Grant ec2:DescribeNatGateways","Retry on throttling","Don't delete NAT gateways out-of-band while kOps state references them"],"tags":["aws","ec2","nat-gateway","api"],"backgroundTag":"aws-api-access-denied","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"}