kubernetes/kops · error
DNS ZoneID not set
Error message
DNS ZoneID not set
What it means
PolicyResource.Open builds the Route53 IAM policy for the cluster's DNS zone. It reads the hosted zone ID from the DNSZone task; if both ZoneID and DNSName are empty it cannot construct the Route53 ARN and returns 'DNS ZoneID not set'. The source comment flags this as a dependency-analysis failure: DNSZone.Find should normally populate ZoneID before Open runs.
Source
Thrown at pkg/model/iam/iam_builder.go:789
// Open produces the AWS IAM policy for the given role
func (b *PolicyResource) Open() (io.Reader, error) {
// Defensive copy before mutation
pb := *b.Builder
if b.DNSZone != nil {
hostedZoneID := fi.ValueOf(b.DNSZone.ZoneID)
if hostedZoneID == "" {
// ZoneID is normally populated by DNSZone.Find before this runs. In dry-run modes that
// skip Find (e.g. `kops get assets`), it may still be empty; fall back to the DNS name
// so the policy renders. The resulting ARN is not a valid Route53 ARN, but the policy
// is not applied in that mode.
hostedZoneID = fi.ValueOf(b.DNSZone.DNSName)
klog.V(4).Infof("Falling back to DNS name %q for IAM policy because ZoneID is empty", hostedZoneID)
}
if hostedZoneID == "" {
// Dependency analysis failure?
return nil, fmt.Errorf("DNS ZoneID not set")
}
pb.HostedZoneID = hostedZoneID
}
policy, err := pb.BuildAWSPolicy()
if err != nil {
return nil, fmt.Errorf("error building IAM policy: %v", err)
}
if policy == nil {
return bytes.NewReader([]byte{}), nil
}
j, err := policy.AsJSON()
if err != nil {
return nil, fmt.Errorf("error building IAM policy: %v", err)
}
return bytes.NewReader([]byte(j)), nil
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Verify the hosted zone still exists: `aws route53 list-hosted-zones` and compare with `kops get cluster -o yaml` (spec.dnsZone / dns name).
- Recreate the hosted zone or fix the DNS configuration in the cluster spec, then rerun `kops update cluster` so DNSZone.Find populates ZoneID.
- If in dry-run, ensure the DNSName is set on the DNSZone task so the fallback ARN path works.
- Upgrade kOps if a recent version changed DNS task dependency ordering; check release notes for PolicyResource/DNSZone fixes.
Defensive patterns
Strategy: fallback
Validate before calling
// Before update, confirm the hosted zone exists and is reachable
zones, err := route53Client.ListHostedZonesByName(&route53.ListHostedZonesByNameInput{DNSName: aws.String(dnsName)})
if err != nil || len(zones.HostedZones) == 0 {
return fmt.Errorf("no Route53 hosted zone found for %s", dnsName)
} Try / catch
r, err := policyResource.Open()
if err != nil {
if strings.Contains(err.Error(), "DNS ZoneID not set") {
// ensure DNSZone task Find() ran; check hosted zone exists in AWS
}
return err
} Prevention
- Never delete the Route53 hosted zone while kOps state references it
- Run `kops update cluster` in full (not modes that skip Find) so DNSZone is populated
- Ensure spec.dnsZone / DNS name is set in the cluster spec
When it happens
Trigger: `kops update cluster` (with DNS managed via Route53) where PolicyResource.Open executes before the DNSZone task has run Find, or the DNS zone record was deleted from AWS so Find returns nothing and DNSName is also unset.
Common situations: The Route53 hosted zone was deleted out-of-band while kOps state still references it; dry-run/CI modes that skip DNS zone lookup; task dependency graph issue after interrupted updates; kops get assets or similar flows where Find is bypassed and even DNSName is empty.
Related errors
- error listing DNS ResourceRecords: %v
- error creating ResourceRecordSets: %v
- error applying DNS changeset for zone %s: %v
- error deleting route53 record %q: %v
- error querying for route53 zones: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/944fdb181d81b643.
Report an issue: GitHub.