kubernetes/kops · error
NextToken set from DescribeNatGateways, but pagination not i
Error message
NextToken set from DescribeNatGateways, but pagination not implemented
What it means
kops' FindNatGateways calls DescribeNatGateways without pagination support; if AWS returns a NextToken (result set larger than one page), it deliberately fails fast rather than silently dropping NAT gateways. This is a defensive limitation error, not an AWS failure.
Source
Thrown at pkg/resources/aws/aws.go:1396
}
}
var resourceTrackers []*resources.Resource
for natGatewayId := range natGatewayIds {
request := &ec2.DescribeNatGatewaysInput{
NatGatewayIds: []string{natGatewayId},
}
response, err := c.EC2().DescribeNatGateways(ctx, request)
if err != nil {
if awsup.AWSErrorCode(err) == "NatGatewayNotFound" {
klog.V(2).Infof("Got NatGatewayNotFound describing NatGateway %s; will treat as already-deleted", natGatewayId)
continue
}
return nil, fmt.Errorf("error from DescribeNatGateways: %v", err)
}
if response.NextToken != nil {
return nil, fmt.Errorf("NextToken set from DescribeNatGateways, but pagination not implemented")
}
for _, ngw := range response.NatGateways {
natGatewayId := aws.ToString(ngw.NatGatewayId)
forceShared := !ownedNatGatewayIds.Has(natGatewayId)
ngwResource := buildNatGatewayResource(ngw, forceShared, clusterName)
resourceTrackers = append(resourceTrackers, ngwResource)
// Don't try to remove ElasticIPs if NatGateway is shared
if ngwResource.Shared {
continue
}
// If we're deleting the NatGateway, we should delete the ElasticIP also
for _, address := range ngw.NatGatewayAddresses {
if address.AllocationId != nil {
request := &ec2.DescribeAddressesInput{}View on GitHub (pinned to 4c8573c808)
Solutions
- Upgrade kops to a version where DescribeNatGateways pagination is implemented.
- Work around by reducing matching NAT gateways (filters on the cluster's VPC only) or running per-VPC.
- Patch locally: convert to ec2.NewDescribeNatGatewaysPaginator and iterate pages like DescribeLaunchTemplates does.
Example fix
// before
response, err := c.EC2().DescribeNatGateways(ctx, request)
if response.NextToken != nil {
return nil, fmt.Errorf("NextToken set from DescribeNatGateways, but pagination not implemented")
}
// after
paginator := ec2.NewDescribeNatGatewaysPaginator(c.EC2(), request)
for paginator.HasMorePages() {
page, err := paginator.NextPage(ctx)
if err != nil {
return nil, fmt.Errorf("error from DescribeNatGateways: %w", err)
}
// process page.NatGateways
} Defensive patterns
Strategy: validation
Validate before calling
if len(natGatewayIDs) > 50 { /* page manually or split into batches — large sets can return NextToken */ } Type guard
func nextTokenSet(resp *ec2.DescribeNatGatewaysOutput) bool { return resp != nil && resp.NextToken != nil } Try / catch
if err != nil && strings.Contains(err.Error(), "pagination not implemented") {
// fall back to per-ID DescribeNatGateways calls which never paginate
return listNatGatewaysOneByOne(ids)
} Prevention
- Use a kops version with paginator-based DescribeNatGateways
- For accounts with many NAT gateways, enumerate per-VPC or per-ID
- When patching, mirror ec2.NewDescribeLaunchTemplatesPaginator usage
When it happens
Trigger: DescribeNatGateways response contains a non-nil NextToken — i.e., more NAT gateways match the filter than fit in a single API page.
Common situations: Enumerating resources in an account/region with many NAT gateways (many large multi-cluster setups) sharing the same VPC filters.
Related errors
- error describing instances: %v
- error describing RouteTables: %v
- error describing NatGateways: %v
- error listing AutoScaling LaunchTemplates: %v
- error from DescribeRouteTables: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/4c7df3dee44448b0.
Report an issue: GitHub.