kubernetes/kops · error

error creating DNS HostedZone %q: %v

Error message

error creating DNS HostedZone %q: %v

What it means

RenderAWS failed to create the Route53 hosted zone: the CreateHostedZone API call returned an error when provisioning a new DNSZone task (no existing zone matched). All Route53 creation failures — permissions, limits, invalid names, conflicting CallerReference — surface through this wrapper.

Source

Thrown at upup/pkg/fi/cloudup/awstasks/dnszone.go:196

	name := aws.ToString(e.DNSName)
	if a == nil {
		request := &route53.CreateHostedZoneInput{}
		request.Name = e.DNSName
		nonce := rand.Int63()
		request.CallerReference = aws.String(strconv.FormatInt(nonce, 10))

		if e.PrivateVPC != nil {
			request.VPC = &route53types.VPC{
				VPCId:     e.PrivateVPC.ID,
				VPCRegion: route53types.VPCRegion(t.Cloud.Region()),
			}
		}

		klog.V(2).Infof("Creating Route53 HostedZone with Name %q", name)

		response, err := t.Cloud.Route53().CreateHostedZone(ctx, request)
		if err != nil {
			return fmt.Errorf("error creating DNS HostedZone %q: %v", name, err)
		}

		e.ZoneID = response.HostedZone.Id
	} else {
		if changes.PrivateVPC != nil {
			request := &route53.AssociateVPCWithHostedZoneInput{
				HostedZoneId: a.ZoneID,
				VPC: &route53types.VPC{
					VPCId:     e.PrivateVPC.ID,
					VPCRegion: route53types.VPCRegion(t.Cloud.Region()),
				},
			}

			changes.PrivateVPC = nil

			klog.V(2).Infof("Updating DNSZone %q", name)

			_, err := t.Cloud.Route53().AssociateVPCWithHostedZone(ctx, request)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped %v cause; if HostedZoneAlreadyExists, set the existing zone's ID in the spec instead of creating a new one
  2. If AccessDenied, grant the kOps IAM role route53:CreateHostedZone (and AssociateVPCWithHostedZone for private zones)
  3. If InvalidDomainName, correct cluster.spec.dns/name to a valid lowercase domain
  4. If TooManyHostedZones, delete unused zones or request a limit increase
  5. If InvalidVPCAssociation, verify the PrivateVPC ID exists in t.Cloud.Region()

Example fix

// before
request.Name = e.DNSName // e.g. "Cluster.Example.COM" → InvalidDomainName
// after
request.Name = aws.String(strings.ToLower(strings.TrimSuffix(aws.ToString(e.DNSName), ".")))
Defensive patterns

Strategy: try-catch

Validate before calling

name := strings.ToLower(strings.TrimSuffix(aws.ToString(e.DNSName), "."))
if name == "" || strings.ContainsAny(name, " _") || net.ParseIP(name) != nil {
    return fmt.Errorf("invalid hosted zone name %q", name)
}
if e.PrivateVPC != nil {
    if _, err := ec2.DescribeVpcs(ctx, &ec2.DescribeVpcsInput{VpcIds: []string{aws.ToString(e.PrivateVPC.ID)}}); err != nil {
        return fmt.Errorf("VPC %s not found/accessible in region: %w", aws.ToString(e.PrivateVPC.ID), err)
    }
}
// confirm no zone already exists with this name
out, _ := r53.ListHostedZonesByName(ctx, &route53.ListHostedZonesByNameInput{DNSName: aws.String(name + ".")})
for _, z := range out.HostedZones {
    if aws.ToString(z.Name) == name+"." {
        return fmt.Errorf("zone %s already exists (%s); reference its ID instead of creating", name, aws.ToString(z.Id))
    }
}

Type guard

func isRetryableRoute53Error(err error) bool {
    switch awsup.AWSErrorCode(err) {
    case "Throttling", "RequestLimitExceeded", "ServiceUnavailable", "InternalError":
        return true
    }
    return false
}

Try / catch

response, err := t.Cloud.Route53().CreateHostedZone(ctx, request)
if err != nil {
    switch awsup.AWSErrorCode(err) {
    case "HostedZoneAlreadyExists":
        // adopt existing zone instead of failing
        return adoptExistingZone(ctx, t, e, err)
    case "TooManyHostedZones":
        return fmt.Errorf("hosted zone limit reached for account: %w", err)
    case "InvalidDomainName":
        return fmt.Errorf("invalid DNS name %q: %w", name, err)
    }
    if isRetryableRoute53Error(err) {
        return retryCreateWithBackoff(ctx, request)
    }
    return fmt.Errorf("error creating DNS HostedZone %q: %w", name, err)
}

Prevention

When it happens

Trigger: CreateHostedZone errors: AccessDenied (no route53:CreateHostedZone), InvalidDomainName (bad DNSName), TooManyHostedZones (account limit, historically 500 public zones), HostedZoneAlreadyExists for a re-used CallerReference, InvalidVPCAssociation inputs for private zones (bad VPC id/region).

Common situations: Public zone for a domain already delegated elsewhere hitting account zone limits; misconfigured cluster DNS name (typo, uppercase, trailing dot issues); IAM role too restricted; creating a private zone with a VPC ID from the wrong region; rate limiting during parallel cluster creation.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/aa58c86fffec9825. Report an issue: GitHub.