kubernetes/kops · error
error finding associated RouteTable to NatGateway: %v
Error message
error finding associated RouteTable to NatGateway: %v
What it means
findNatGatewayFromRouteTable locates the NAT gateway via the default route (0.0.0.0/0 target nat-...) on the private route table. This error wraps a failure to fetch that route table with findRouteTableByID, aborting the NatGateway Find flow.
Source
Thrown at upup/pkg/fi/cloudup/awstasks/natgateway.go:211
}
if response == nil || len(response.NatGateways) == 0 {
klog.V(2).Infof("Unable to find NatGateway %q", id)
return nil, nil
}
if len(response.NatGateways) != 1 {
return nil, fmt.Errorf("found multiple NatGateways with id %q", id)
}
return &response.NatGateways[0], nil
}
func findNatGatewayFromRouteTable(ctx context.Context, cloud awsup.AWSCloud, routeTable *RouteTable) (*ec2types.NatGateway, error) {
// Find via route on private route table
if routeTable.ID != nil {
klog.V(2).Infof("trying to match NatGateway via RouteTable %s", *routeTable.ID)
rt, err := findRouteTableByID(ctx, cloud, *routeTable.ID)
if err != nil {
return nil, fmt.Errorf("error finding associated RouteTable to NatGateway: %v", err)
}
if rt != nil {
var natGatewayIDs []*string
natGatewayIDsSeen := map[string]bool{}
for _, route := range rt.Routes {
if route.NatGatewayId != nil && route.State != ec2types.RouteStateBlackhole && !natGatewayIDsSeen[*route.NatGatewayId] {
natGatewayIDs = append(natGatewayIDs, route.NatGatewayId)
natGatewayIDsSeen[*route.NatGatewayId] = true
}
}
if len(natGatewayIDs) == 0 {
klog.V(2).Infof("no NatGateway found in route table %s", *rt.RouteTableId)
} else if len(natGatewayIDs) > 1 {
clusterName, ok := routeTable.Tags[awsup.TagClusterName]
if !ok {
return nil, fmt.Errorf("Could not find '%s' tag from route table", awsup.TagClusterName)View on GitHub (pinned to 4c8573c808)
Solutions
- Inspect the wrapped %v cause (AccessDenied vs NotFound vs throttling) and address accordingly
- Verify the route table ID still exists with `aws ec2 describe-route-tables --route-table-ids <id>`; recreate/retag if deleted out-of-band
- Ensure the kops controller/CLI IAM policy grants ec2:DescribeRouteTables
- Retry on transient/throttling errors
Example fix
// before: IAM lacking describe access → error
// after: attach required permission
{"Effect":"Allow","Action":["ec2:DescribeRouteTables","ec2:DescribeNatGateways"],"Resource":"*"} Defensive patterns
Strategy: try-catch
Validate before calling
_, err := ec2Client.DescribeRouteTables(ctx, &ec2.DescribeRouteTablesInput{RouteTableIds: []string{rtbID}})
if err != nil { return fmt.Errorf("route table %s unreachable: %w", rtbID, err) } Type guard
func routeTableExists(ctx context.Context, c awsup.AWSCloud, id string) bool {
out, err := findRouteTableByID(ctx, c, id)
return err == nil && out != nil
} Try / catch
ngw, err := findNatGatewayFromRouteTable(ctx, cloud, rt)
if err != nil {
if isThrottling(err) { /* backoff and retry */ }
if strings.Contains(err.Error(), "InvalidRouteTableID.NotFound") { /* stale table — resync kops state */ }
} Prevention
- Keep ec2:DescribeRouteTables in the IAM policy
- Don't delete route tables managed by kops out-of-band
- Back off on throttling when reconciling many route tables
When it happens
Trigger: findRouteTableByID(ctx, cloud, *routeTable.ID) returns err — DescribeRouteTables API failure (AccessDenied, throttling, invalid route table ID, network error) while reconciling a private RouteTable task.
Common situations: Route table deleted out-of-band leaving stale IDs in kops state; IAM missing ec2:DescribeRouteTables; transient AWS API errors during `kops update cluster --reconverge` or `kops get cluster` with cloud lookups.
Related errors
- error listing RouteTables: %v
- describing instance for arn %q
- error terminating instances: %v
- error describing instances: %v
- error describing addresses: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/7915da10efd7d74f.
Report an issue: GitHub.