{"record":{"id":"0bbf4a50d9bf1ef2","repo":"kubernetes/kops","slug":"failed-to-find-domain-for-cluster-s","errorCode":null,"errorMessage":"failed to find domain for cluster: %s","messagePattern":"failed to find domain for cluster: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/digitalocean/resources.go","lineNumber":156,"sourceCode":"\treturn resourceTrackers, nil\n}\n\nfunc listDNS(cloud fi.Cloud, clusterName string) ([]*resources.Resource, error) {\n\tc := cloud.(do.DOCloud)\n\tdomains, _, err := c.DomainService().List(context.TODO(), &godo.ListOptions{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list domains: %s\", err)\n\t}\n\n\tvar domainName string\n\tfor _, domain := range domains {\n\t\tif strings.HasSuffix(clusterName, domain.Name) {\n\t\t\tdomainName = domain.Name\n\t\t}\n\t}\n\n\tif domainName == \"\" {\n\t\treturn nil, fmt.Errorf(\"failed to find domain for cluster: %s\", clusterName)\n\t}\n\n\trecords, err := getAllRecordsByDomain(c, domainName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list records for domain %s: %s\", domainName, err)\n\t}\n\n\tvar resourceTrackers []*resources.Resource\n\tfor _, record := range records {\n\t\tif !strings.HasSuffix(dns.EnsureDotSuffix(record.Name)+domainName, clusterName) {\n\t\t\tcontinue\n\t\t}\n\n\t\t// kops for digitalocean should only create A records\n\t\t// in the future that may change but for now this provides a safe filter\n\t\t// in case users assign NS records for the cluster subdomain\n\t\tif record.Type != \"A\" {\n\t\t\tcontinue","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/digitalocean/resources.go#L138-L174","documentation":"listDNS iterated all DO domains and none of their names is a suffix of the clusterName, so kOps cannot locate which DNS zone hosts the cluster's records. Thrown as a hard failure during resource discovery on delete/dump.","triggerScenarios":"No domain in the DO account satisfies strings.HasSuffix(clusterName, domain.Name), e.g. cluster name \"k8s.example.com\" but account only has domain \"other.com\", or the domain was deleted out-of-band.","commonSituations":"Cluster was created with a DNS zone managed outside DigitalOcean (e.g. Route53) while kops tries the DO listing; domain deleted manually; cluster name typo; trailing dot mismatches.","solutions":["Ensure a DO domain exists whose name matches the cluster name suffix (doctl compute domain create example.com)","Confirm the cluster name exactly matches the registered kops cluster (kops get clusters)","If DNS is not managed in DO, use the correct --cloud / dns configuration for deletion","Recreate/import the domain if it was deleted accidentally"],"exampleFix":"// before\nkops delete cluster --name k8s.mistyped.com --cloud digitalocean\n// after\nkops delete cluster --name k8s.example.com --cloud digitalocean  # matches existing DO domain example.com","handlingStrategy":"validation","validationCode":"domainName := \"\"\nfor _, d := range domains {\n\tif strings.HasSuffix(strings.TrimSuffix(clusterName, \".\"), d.Name) {\n\t\tdomainName = d.Name\n\t\tbreak\n\t}\n}\nif domainName == \"\" {\n\treturn fmt.Errorf(\"no DO domain matches cluster %q; existing: %v\", clusterName, domainNames(domains))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create the DO domain zone before creating the cluster","Keep cluster name aligned with a domain that exists in the DO account","If DNS is external (e.g. Route53), configure kops DNS accordingly instead of relying on DO","Confirm exact cluster name with `kops get clusters` before deleting"],"tags":["digitalocean","dns","configuration"],"backgroundTag":"domain-not-found","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"}