kubernetes/kops · error

error pre-creating DNS records: %v

Error message

error pre-creating DNS records: %v

What it means

precreateDNS batches the DNS changes needed to pre-create records (e.g. api, api.internal, bastion names) and applies them via changeset.Apply(ctx). If the provider rejects or fails the change, the underlying error is wrapped as 'error pre-creating DNS records'. This happens late in cluster provisioning after the model is built.

Source

Thrown at upup/pkg/fi/cloudup/dns.go:236

		}
		if !foundTXT {
			if cluster.Spec.ExternalDNS != nil && cluster.Spec.ExternalDNS.Provider == kops.ExternalDNSProviderExternalDNS {
				domain := recordKey.hostname
				if ip == kopsdns.PlaceholderIPv6 {
					domain = "aaaa-" + domain
				}
				changeset.Add(rrs.New(domain, []string{fmt.Sprintf("\"heritage=external-dns,external-dns/owner=kops-%s\"", cluster.ObjectMeta.Name)}, PlaceholderTTL, rrstype.TXT))
			}
		}
		created = append(created, recordKey)
	}

	if len(created) != 0 {
		klog.Infof("Pre-creating DNS records")

		err := changeset.Apply(ctx)
		if err != nil {
			return fmt.Errorf("error pre-creating DNS records: %v", err)
		}
		klog.V(2).Infof("Pre-created DNS names: %v", created)
	}

	return nil
}

// buildPrecreateDNSHostnames returns the hostnames we should precreate
func buildPrecreateDNSHostnames(cluster *kops.Cluster) []recordKey {
	var recordKeys []recordKey
	internalType := rrstype.A
	if cluster.Spec.IsIPv6Only() {
		internalType = rrstype.AAAA
	}

	hasAPILoadbalancer := cluster.Spec.API.LoadBalancer != nil
	useLBForInternalAPI := hasAPILoadbalancer && cluster.Spec.API.LoadBalancer.UseForInternalAPI

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped %v cause for the provider-specific reason (e.g. InvalidChangeBatch, AccessDenied)
  2. Delete stale records for the same cluster name in the hosted zone from previous attempts
  3. Grant route53:ChangeResourceRecordSets / Cloud DNS write permissions to the credentials kOps uses
  4. Re-run kops — DNS pre-creation is idempotent for records already created

Example fix

// before
kops create cluster --name api.example.com ...  # stale CNAME for api.example.com exists
// after
# remove conflicting record, then rerun
aws route53 list-resource-record-sets --hosted-zone-id Z...
aws route53 change-resource-record-sets ... --change-batch '{"Changes":[{"Action":"DELETE",...}]}'
Defensive patterns

Strategy: try-catch

Validate before calling

aws route53 list-resource-record-sets --hosted-zone-id Z... | grep -F 'api.<cluster>'
# remove stale records for the cluster name before creating

Try / catch

err := changeset.Apply(ctx)
if err != nil {
    klog.Warningf("DNS apply failed: %v; check permissions (route53:ChangeResourceRecordSets) and conflicting records", err)
    return err
}

Prevention

When it happens

Trigger: changeset.Apply fails while running `kops create cluster`: insufficient DNS permissions (route53:ChangeResourceRecordSets), duplicate/conflicting records in the zone, zone state changed concurrently, or provider API errors.

Common situations: Records already exist from a previous cluster with the same name (CNAME conflict with existing alias records); AWS credentials without write access; hosted zone deleted mid-run; Route53 throttling.

Related errors


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