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
- Inspect the wrapped %v cause for the provider-specific reason (e.g. InvalidChangeBatch, AccessDenied)
- Delete stale records for the same cluster name in the hosted zone from previous attempts
- Grant route53:ChangeResourceRecordSets / Cloud DNS write permissions to the credentials kOps uses
- 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
- Grant DNS write permissions to kops credentials
- Delete leftover records from previous clusters with the same name
- Avoid concurrent kops runs against the same hosted zone
- Retry idempotently — already-created records are skipped
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
- failed to apply resource record set: %s, err: %s
- failed to delete record for domain %s: %d
- failed to list dns zones: %s
- failed to extract recordsets pages for zone %s: %v
- error fetching DNS HostedZone %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/827f5f1ebcc43757.
Report an issue: GitHub.