kubernetes/kops · error

failed to extract recordsets pages for zone %s: %v

Error message

failed to extract recordsets pages for zone %s: %v

What it means

Once the cluster zone is identified, ListDNSRecordsets pages through the zone's recordsets via the Designate client. A failure is wrapped with this message including the zone name. It aborts cleanup because the A records belonging to the cluster (apiserver etc.) cannot be enumerated.

Source

Thrown at pkg/resources/openstack/dns.go:57

	if err != nil {
		return nil, fmt.Errorf("failed to list dns zones: %s", err)
	}

	var clusterZone zones.Zone
	for _, zone := range zs {
		if strings.HasSuffix(os.clusterName, strings.TrimSuffix(zone.Name, ".")) {
			clusterZone = zone
			break
		}
	}

	if clusterZone.ID == "" {
		return nil, fmt.Errorf("failed to find cluster dns zone")
	}

	rrs, err := os.osCloud.ListDNSRecordsets(clusterZone.ID, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to extract recordsets pages for zone %s: %v", clusterZone.Name, err)
	}

	var resourceTrackers []*resources.Resource
	for _, rr := range rrs {
		if rr.Type != "A" || !strings.HasSuffix(strings.TrimSuffix(rr.Name, "."), os.clusterName) {
			continue
		}

		resourceTracker := &resources.Resource{
			Name: rr.Name,
			ID:   rr.ID,
			Type: typeDNSRecord,
			Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
				return os.osCloud.DeleteDNSRecordset(clusterZone.ID, r.ID)
			},
			Obj: rr,
		}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Re-run 'kops delete cluster' after transient errors
  2. Verify the zone still exists with 'openstack zone show <zone>'
  3. Refresh OpenStack credentials / re-source openrc
  4. Check RBAC (reader/member role) on the DNS project
  5. Check Designate service health and API endpoint

Example fix

// before
rrs, err := os.osCloud.ListDNSRecordsets(clusterZone.ID, nil)
if err != nil {
	return nil, fmt.Errorf("failed to extract recordsets pages for zone %s: %v", clusterZone.Name, err)
}
// after
rrs, err := os.osCloud.ListDNSRecordsets(clusterZone.ID, nil)
if err != nil {
	return nil, fmt.Errorf("failed to extract recordsets pages for zone %s: %w", clusterZone.Name, err)
}
Defensive patterns

Strategy: retry

Validate before calling

// Confirm zone still exists before listing recordsets
zs, _ := os.osCloud.ListDNSZones(zones.ListOpts{})
// ensure clusterZone.ID is among zs before calling ListDNSRecordsets

Type guard

func isZoneMissing(err error) bool { _, ok := err.(gophercloud.ErrDefault404); return ok }

Try / catch

rrs, err := os.osCloud.ListDNSRecordsets(clusterZone.ID, nil)
if err != nil {
	if isZoneMissing(err) { /* zone gone: treat recordsets as cleaned */ }
	return nil, fmt.Errorf("failed to extract recordsets pages for zone %s: %w", clusterZone.Name, err)
}

Prevention

When it happens

Trigger: os.osCloud.ListDNSRecordsets(clusterZone.ID, nil) errors: zone ID no longer valid (zone deleted concurrently), auth token expiry mid-operation, network error, pagination failure, or RBAC denying recordset reads.

Common situations: Zone deleted between the zone-list and recordset-list calls; expired Keystone token during a long-running delete; Designate API outage; insufficient role assignment on the zone.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/aa12e24b1a113f04. Report an issue: GitHub.