{"record":{"id":"daedca9ac42047b7","repo":"kubernetes/kops","slug":"error-deleting-gce-dns-resource-record-set-v","errorCode":null,"errorMessage":"error deleting GCE DNS resource record set %v","messagePattern":"error deleting GCE DNS resource record set (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/gce/gce.go","lineNumber":1387,"sourceCode":"\n\treturn resourceTrackers, nil\n}\n\nfunc deleteDNSRecords(cloud fi.Cloud, r []*resources.Resource) error {\n\tc := cloud.(gce.GCECloud)\n\tvar records []*clouddns.ResourceRecordSet\n\tvar zoneName string\n\n\tfor _, record := range r {\n\t\tr := record.Obj.(*clouddns.ResourceRecordSet)\n\t\tzoneName = record.GroupKey\n\t\trecords = append(records, r)\n\t}\n\n\tchange := clouddns.Change{Deletions: records, Kind: \"dns#change\", IsServing: true}\n\t_, err := c.CloudDNS().Changes().Create(c.Project(), zoneName, &change)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error deleting GCE DNS resource record set %v\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":1369,"sourceCodeEnd":1391,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/gce/gce.go#L1369-L1391","documentation":"Returned by deleteDNSRecords when the Cloud DNS Changes().Create call carrying the record Deletions fails. kops issues one change batch deleting all cluster A records from the zone; if the API rejects the change, this error is surfaced during cluster deletion. The wrapped error contains the API-level reason (conflict, not-found, permissions).","triggerScenarios":"Changes().Create(project, zoneName, &change{Deletions: records}) fails: the zone no longer exists, records were already deleted/modified (change conflict / precondition failure), insufficient DNS write permission, or API outage.","commonSituations":"Running kops delete cluster twice in parallel (second run conflicts with already-deleted records); zone deleted out-of-band in the GCP console; service account lacks roles/dns.admin so delete is forbidden; stale discovery data referencing outdated records.","solutions":["Verify the zone still exists and the records are present: gcloud dns record-sets list --zone <zone> --project <project>.","Ensure the service account has roles/dns.admin (write) on the project — read-only roles cause 'forbidden' here.","If records were already removed by a prior run, re-run discovery/delete; the leftover records simply no longer exist.","For precondition/conflict errors, retry after the in-flight change completes; avoid concurrent kops delete runs against the same cluster."],"exampleFix":"// before: parallel deletes conflict\nkubectl-ops delete cluster A & kops delete cluster A & wait\n// after: single serialized delete\nkops delete cluster A --yes","handlingStrategy":"try-catch","validationCode":"zone, err := dnsService.ManagedZones.Get(project, zoneName).Do()\nif err != nil {\n    return fmt.Errorf(\"zone %s not accessible, skip delete change: %w\", zoneName, err)\n}\nrs, err := dnsService.ResourceRecordSets.List(project, zoneName).Do()\nif err != nil {\n    return err\n}\nif len(rs.Rrsets) == 0 {\n    return nil // nothing to delete; skip Changes().Create\n}","typeGuard":"var apiErr *googleapi.Error\nif errors.As(err, &apiErr) && apiErr.Code == 404 {\n    // zone or records already deleted; treat as success/no-op\n}","tryCatchPattern":"_, err := c.CloudDNS().Changes().Create(project, zoneName, &change)\nvar apiErr *googleapi.Error\nif errors.As(err, &apiErr) {\n    if apiErr.Code == 404 || apiErr.Code == 409 {\n        // already deleted or concurrent change: re-list and reconcile, don't hard-fail\n    } else if apiErr.Code == 403 {\n        // missing roles/dns.admin: fix IAM\n    }\n}","preventionTips":["Never run two kops delete cluster operations against the same cluster concurrently.","Ensure the service account has roles/dns.admin before deletion flows.","Re-run discovery immediately before issuing deletions so record sets are fresh.","Treat 404/409 on delete changes as idempotent success in automation."],"tags":["gce","dns","gcp","deletion"],"backgroundTag":"gcp-api-auth-failure","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}