{"record":{"id":"b0312bf1ea7f39ee","repo":"kubernetes/kops","slug":"error-querying-for-route53-zones-w","errorCode":null,"errorMessage":"error querying for route53 zones: %w","messagePattern":"error querying for route53 zones: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/aws/aws.go","lineNumber":1819,"sourceCode":"\tctx := context.TODO()\n\tvar resourceTrackers []*resources.Resource\n\n\tc := cloud.(awsup.AWSCloud)\n\n\t// Normalize cluster name, with leading \".\"\n\tclusterName = \".\" + strings.TrimSuffix(clusterName, \".\")\n\n\t// TODO: If we have the zone id in the cluster spec, use it!\n\tvar zones []route53types.HostedZone\n\t{\n\t\tklog.V(2).Infof(\"Querying for all route53 zones\")\n\n\t\trequest := &route53.ListHostedZonesInput{}\n\t\tpaginator := route53.NewListHostedZonesPaginator(c.Route53(), request)\n\t\tfor paginator.HasMorePages() {\n\t\t\tpage, err := paginator.NextPage(ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error querying for route53 zones: %w\", err)\n\t\t\t}\n\t\t\tfor _, zone := range page.HostedZones {\n\t\t\t\tzoneName := aws.ToString(zone.Name)\n\t\t\t\tzoneName = \".\" + strings.TrimSuffix(zoneName, \".\")\n\n\t\t\t\tif strings.HasSuffix(clusterName, zoneName) {\n\t\t\t\t\tzones = append(zones, zone)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor i := range zones {\n\t\t// Be super careful because we close over this later (in groupDeleter)\n\t\tzone := zones[i]\n\n\t\thostedZoneID := strings.TrimPrefix(aws.ToString(zone.Id), \"/hostedzone/\")\n","sourceCodeStart":1801,"sourceCodeEnd":1837,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/aws/aws.go#L1801-L1837","documentation":"ListRoute53Records fails while paginating ListHostedZones; kOps wraps the error as 'error querying for route53 zones'. This is the discovery step that finds zones whose name is a suffix of the cluster name, before enumerating records to delete.","triggerScenarios":"ListHostedZones pagination returns AccessDenied (missing route53:ListHostedZones), ThrottlingException, or a transient/network error while iterating hosted zones.","commonSituations":"Credentials scoped to a specific zone ARN but lacking global route53:ListHostedZones; accounts with many hosted zones hitting pagination limits; DNS API transient failures during 'kops delete cluster'.","solutions":["Grant route53:ListHostedZones to the credentials (account-wide permission, not per-zone).","Retry; throttling and transient errors usually resolve on a subsequent pass.","Verify the AWS region/credentials and that STS session is valid.","Use aws route53 list-hosted-zones CLI with the same credentials to reproduce and isolate.","If the account has very many zones, ensure credentials allow full listing rather than relying on partial results."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight: can we list zones at all?\n_, err := c.Route53().ListHostedZones(ctx, &route53.ListHostedZonesInput{MaxItems: aws.Int32(1)})\nif err != nil { /* credentials lack route53:ListHostedZones or API unreachable — fix before proceeding */ }","typeGuard":null,"tryCatchPattern":"page, err := paginator.NextPage(ctx)\nif err != nil {\n    if awsup.AWSErrorCode(err) == \"ThrottlingException\" {\n        time.Sleep(backoff); continue\n    }\n    return nil, fmt.Errorf(\"error querying for route53 zones: %w\", err)\n}","preventionTips":["Grant account-wide route53:ListHostedZones (it cannot be scoped to one zone).","Add pagination-aware retry with backoff.","Run a 1-item pre-flight to fail fast on IAM/credential issues.","Verify region/STS session validity before teardown.","Avoid running many Route53-heavy operations concurrently."],"tags":["aws","route53","dns","listing"],"backgroundTag":"aws-api-list-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"}