{"record":{"id":"c183933b3edfb68c","repo":"kubernetes/kops","slug":"error-deleting-route53-record-q-v","errorCode":null,"errorMessage":"error deleting route53 record %q: %v","messagePattern":"error deleting route53 record %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/aws/aws.go","lineNumber":1795,"sourceCode":"\t\tnames = append(names, resourceTracker.Name)\n\t\tchanges = append(changes, route53types.Change{\n\t\t\tAction:            route53types.ChangeActionDelete,\n\t\t\tResourceRecordSet: resourceTracker.Obj.(*route53types.ResourceRecordSet),\n\t\t})\n\t}\n\thuman := strings.Join(names, \", \")\n\tklog.V(2).Infof(\"Deleting route53 records %q\", human)\n\n\tchangeBatch := &route53types.ChangeBatch{\n\t\tChanges: changes,\n\t}\n\trequest := &route53.ChangeResourceRecordSetsInput{\n\t\tHostedZoneId: zone.Id,\n\t\tChangeBatch:  changeBatch,\n\t}\n\t_, err := c.Route53().ChangeResourceRecordSets(ctx, request)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error deleting route53 record %q: %v\", human, err)\n\t}\n\treturn nil\n}\n\nfunc ListRoute53Records(cloud fi.Cloud, vpcID, clusterName string) ([]*resources.Resource, error) {\n\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","sourceCodeStart":1777,"sourceCodeEnd":1813,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/aws/aws.go#L1777-L1813","documentation":"deleteRoute53Records wraps a failed Route53 ChangeResourceRecordSets call (used to delete the batch of records for one resource) with a human-readable record name. Unlike the ELB/EC2 deleters, there is no IsDependencyViolation special-casing — every API error becomes this wrapped error.","triggerScenarios":"ChangeResourceRecordSets fails: InvalidChangeBatch (malformed record or a record doesn't match exactly), NoSuchHostedZone, prior conditional update conflict, AccessDenied on route53:ChangeResourceRecordSets, or throttling.","commonSituations":"Records were modified manually in Route53 so the delete batch no longer matches; hosted zone deleted externally mid-teardown; DNSSEC/SOA/NS records that can't be deleted; cross-account zone access issues.","solutions":["Check the hosted zone still exists (aws route53 list-hosted-zones) and that kOps targets the right zone ID.","Compare the record set in Route53 with what kOps tries to delete — manually edited records cause InvalidChangeBatch.","Grant route53:ChangeResourceRecordSets on the zone in the IAM policy.","Retry after transient throttling/5xx; Route53 API writes are rate-limited.","Delete conflicting/mismatched records manually, then re-run kOps cleanup."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify the zone and the exact record still exist before the ChangeBatch\nzones, err := c.Route53().ListHostedZones(ctx, &route53.ListHostedZonesInput{})\n// match zone.Id, then:\nrrs, err := c.Route53().ListResourceRecordSets(ctx, &route53.ListResourceRecordSetsInput{\n    HostedZoneId: zone.Id, StartRecordName: aws.String(name),\n})\n// if no matching record with same type/value, skip the delete","typeGuard":null,"tryCatchPattern":"_, err := c.Route53().ChangeResourceRecordSets(ctx, request)\nif err != nil {\n    if awsup.AWSErrorCode(err) == \"InvalidChangeBatch\" { /* record mismatch: verify via ListResourceRecordSets */ }\n    if awsup.AWSErrorCode(err) == \"NoSuchHostedZone\" { return nil /* zone gone: done */ }\n    return err\n}","preventionTips":["Don't hand-edit cluster DNS records while kOps manages them.","Verify zone ID and record values match exactly (case, trailing dot) before the change batch.","Grant route53:ChangeResourceRecordSets on the zone.","Treat NoSuchHostedZone as already-cleaned-up.","Check the ChangeInfo/ErrorMessages in InvalidChangeBatch for the offending record."],"tags":["aws","route53","dns","deletion"],"backgroundTag":"aws-api-delete-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"}