kubernetes/kops · error

failed to delete record %s: %w

Error message

failed to delete record %s: %w

What it means

Wrap-around error returned by DeleteDNSRecord when the Scaleway Domains API UpdateDNSZoneRecords fails for a non-404 reason while removing a cluster's DNS record. 404 is explicitly treated as success (record already deleted); any other failure is wrapped with the record name and the SDK error via %w.

Source

Thrown at upup/pkg/fi/cloudup/scaleway/cloud.go:543

func (s *scwCloudImplementation) DeleteDNSRecord(record *domain.Record, clusterName string) error {
	domainName := strings.SplitN(clusterName, ".", 2)[1]
	recordDeleteRequest := &domain.UpdateDNSZoneRecordsRequest{
		DNSZone: domainName,
		Changes: []*domain.RecordChange{
			{
				Delete: &domain.RecordChangeDelete{
					ID: scw.StringPtr(record.ID),
				},
			},
		},
	}
	_, err := s.domainAPI.UpdateDNSZoneRecords(recordDeleteRequest)
	if err != nil {
		if is404Error(err) {
			klog.V(8).Infof("DNS record %q (%s) was already deleted", record.Name, record.ID)
			return nil
		}
		return fmt.Errorf("failed to delete record %s: %w", record.Name, err)
	}
	return nil
}

func (s *scwCloudImplementation) DeleteLoadBalancer(loadBalancer *lb.LB) error {
	ipsToRelease := loadBalancer.IP

	// We delete the load-balancer once it's in a stable state
	_, err := s.lbAPI.WaitForLb(&lb.ZonedAPIWaitForLBRequest{
		LBID: loadBalancer.ID,
		Zone: s.zone,
	})
	if err != nil {
		if is404Error(err) {
			klog.V(8).Infof("Load-balancer %q (%s) was already deleted", loadBalancer.Name, loadBalancer.ID)
			return nil
		}
		return fmt.Errorf("waiting for load-balancer: %w", err)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the DNS zone exists and is in the same project: `scw dns zone list`.
  2. Check IAM permissions of the kops principal for the domains API.
  3. Reproduce the exact record-delete payload with `scw dns zone update-records` to see the raw API error.
  4. Retry with backoff on 429/5xx; re-run `kops delete cluster` — 404s are already tolerated.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify DNS zone exists in this project before deleting records
_, err := domain.NewAPI(client).ListDNSZones(&domain.ListDNSZonesRequest{ProjectID: projectID})
// confirm the cluster's zone appears in the result

Try / catch

if err := kopsDeleteCluster(); err != nil {
  if strings.Contains(err.Error(), "failed to delete record") {
    // inspect record/zone state; a re-run tolerates 404 (already deleted)
    return nil // or log and continue teardown
  }
  return err
}

Prevention

When it happens

Trigger: UpdateDNSZoneRecords failure other than 404: DNS zone not found / not owned by the project (wrong dnsZone in cluster config), invalid record payload, IAM permission missing on the domain, API outage or rate limit.

Common situations: Cluster's DNS zone was deleted or moved to another project before teardown; kops principal lacks domains permissions; misconfigured `dnsZone` suffix in cluster spec; transient domains API failure during `kops delete cluster`.

Related errors


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