{"record":{"id":"ed7e2fd0b7715f2b","repo":"kubernetes/kops","slug":"dnszone-not-set","errorCode":null,"errorMessage":"DNSZone not set","messagePattern":"DNSZone not set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/apply_cluster.go","lineNumber":312,"sourceCode":"\t\t\t\treturn nil, fmt.Errorf(\"kops version older than last used to update the cluster\")\n\t\t\t}\n\t\t} else if err != os.ErrNotExist {\n\t\t\treturn nil, fmt.Errorf(\"error reading last kops version used to update: %v\", err)\n\t\t}\n\t}\n\n\tcloud := c.Cloud\n\n\terr = validation.DeepValidate(c.Cluster, c.InstanceGroups, true, c.Clientset.VFSContext(), cloud)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif cluster.Spec.KubernetesVersion == \"\" {\n\t\treturn nil, fmt.Errorf(\"KubernetesVersion not set\")\n\t}\n\tif cluster.Spec.DNSZone == \"\" && cluster.PublishesDNSRecords() {\n\t\treturn nil, fmt.Errorf(\"DNSZone not set\")\n\t}\n\n\tl := &Loader{}\n\tl.Init()\n\n\tkeyStore, err := c.Clientset.KeyStore(cluster)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsshCredentialStore, err := c.Clientset.SSHCredentialStore(cluster)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsecretStore, err := c.Clientset.SecretStore(cluster)\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/apply_cluster.go#L294-L330","documentation":"Run() requires spec.dnsZone to be set whenever the cluster publishes DNS records (cluster.PublishesDNSRecords()). Internal gossip clusters skip this, but any cluster relying on DNS for API/node discovery must have a dnsZone, so Run fails fast when it is empty.","triggerScenarios":"Running kops update cluster/apply on a public cluster where spec.dnsZone is empty and the cluster still publishes DNS records (not gossip/None topology).","commonSituations":"Hand-built or templated cluster spec missing spec.dnsZone; switching an existing cluster spec to a topology that requires DNS without adding the zone; users of gossip clusters who set a topology that re-enables DNS publishing.","solutions":["Set spec.dnsZone to an existing route53/GCS/DNS zone in `kops edit cluster` (e.g. dnsZone: example.com) and rerun.","Create the DNS zone first if none exists (kops create cluster --dns-zone=example.com or your cloud's zone tooling).","If the cluster is truly meant to be gossip-only (Kubernetes internally), configure topology so the cluster uses gossip (e.g. --topology internal with gossip DNS) — otherwise DNS publishing is required."],"exampleFix":"// before\nspec:\n  kubernetesVersion: 1.29.2\n// after\nspec:\n  kubernetesVersion: 1.29.2\n  dnsZone: example.com","handlingStrategy":"validation","validationCode":"if cluster.Spec.DNSZone == \"\" && cluster.PublishesDNSRecords() {\n    return fmt.Errorf(\"spec.dnsZone is required for clusters publishing DNS records\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass --dns-zone explicitly at `kops create cluster` time.","Ensure the DNS zone exists in the target cloud account before cluster creation.","Do not switch topologies without updating spec.dnsZone accordingly."],"tags":["dns","validation","cluster-spec"],"backgroundTag":"missing-required-argument","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"}