Repository navigation
Kubernetes app: kubeadm join fails when cluster DNS domain is not cluster.local #2372
Description
Description
When using a custom cluster DNS domain (e.g., cozy.local instead of the default cluster.local), the managed Kubernetes app's worker nodes fail to join the cluster due to DNS resolution failure.
Environment
- Cozystack v1.1.4
- Talos v1.12.6
- 6-node bare metal cluster (Hetzner)
- Cluster DNS domain:
cozy.local
Steps to Reproduce
- Have a Cozystack cluster with DNS domain set to
cozy.local(notcluster.local) - Create a Kubernetes app in a tenant namespace
- Control plane comes up successfully
- Worker VMs boot but never join the cluster
- Machines stay in "Provisioned" phase, eventually hit
NodeStartupTimeout
Root Cause
The chart generates kubeadm join configuration with a partial FQDN:
apiServerEndpoint: kubernetes-botz-infra.tenant-simbotix.svc:6443This assumes the DNS search path includes the cluster domain suffix. However, worker VMs (KubeVirt bridge networking) receive DNS configuration via DHCP from the virt-launcher, which does not include the cluster domain in the search path.
Verification:
nslookup kubernetes-botz-infra.tenant-simbotix.svc→ NXDOMAINnslookup kubernetes-botz-infra.tenant-simbotix.svc.cozy.local→ 10.96.162.69 ✅
The konnectivity server confirms no agents connect:
E0411 server.go:528] "Failed to get a backend" err="No agent available"
Expected Behavior
Worker nodes should join the cluster regardless of the cluster DNS domain.
Suggested Fix
Use the fully qualified domain name including the cluster DNS domain in the kubeadm join config, or use the ClusterIP directly.
Workaround Attempted
Setting the host field does not change the kubeadm join apiServerEndpoint.
Activity
dosubot commentedon Apr 11, 2026
Hi Rajesh Medampudi (@medampudi)! I'm Dosu and I’m helping the cozystack team.
This is a confirmed bug. The kubeadm join template in
packages/apps/kubernetes/templates/cluster.yamlconstructs theapiServerEndpointusing a short service DNS name without the cluster domain suffix [1]:This relies on DNS search domains being present in the worker VM's
/etc/resolv.conf, which doesn't hold when worker VMs get their DNS config via DHCP from the KubeVirt virt-launcher.The same short FQDN pattern also affects Cilium's
k8sServiceHostconfiguration [2]:This is actually the same class of bug that was already fixed for monitoring agents in v1.0.0-rc.1 —
vmagentandfluent-bitwere failing because service addresses used short DNS names without the cluster domain suffix [3]. That fix used the_cluster.cluster-domainvalue to construct full FQDNs [4]:{{- $clusterDomain := (index .Values._cluster "cluster-domain") | default "cluster.local" }}The fix here would follow the same pattern — append the cluster domain to both the kubeadm join endpoint and the Cilium
k8sServiceHost:Worth noting: there's also a separate issue tracking DNS resolution problems with
.localdomains specifically, since RFC 6762 reserves.localfor mDNS andsystemd-resolvedroutes those queries to mDNS instead of CoreDNS. That could compound this issue for VMs using systemd-resolved.To reply, just mention @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

medampudi commentedon Apr 11, 2026
Root Cause Confirmed (2026-04-11)
After a full cluster reinstall with
clusterDomain: cluster.local, the managed K8s worker nodes still fail to join.The actual issue
The kubeadm join config generated by Kamaji/CAPI uses a partial FQDN:
This requires DNS search domain expansion to resolve. However, KubeVirt worker VMs don't have the cluster's search domains in their
/etc/resolv.conf— they get DNS via DHCP which only provides the nameserver (10.96.0.10) but not the search domains.Proof
From a pod in the same namespace (which HAS the search domains):
Even a pod with search domains gets NXDOMAIN on the partial name! The full FQDN works fine.
Fix needed
Kamaji should generate the full FQDN in the kubeadm join config:
This is independent of the cluster domain setting (
cozy.localvscluster.local) — the issue is that the.svcsuffix without the cluster domain never resolves.Environment
fix(kubernetes): use full FQDN for kubeadm join apiServerEndpoint
medampudi commentedon May 3, 2026
Andrei Kvapil (@kvaps) any thoughts on this one? Root cause confirmed in my comment above (Kamaji-generated kubeadm join config uses partial
.svcFQDN that requires search-domain expansion not present in KubeVirt VM/etc/resolv.conf). Happy to PR the fix in Kamaji's join-config template if you agree on the direction.dosubot commentedon Aug 2, 2026
Hi, Rajesh Medampudi (@medampudi). I'm Dosu, and I'm helping the cozystack team manage their backlog and am marking this issue as stale.
Issue Summary
...svc:6443) instead of a full FQDN./etc/resolv.conf.NXDOMAIN, while the full...svc.cluster.localname resolves correctly from within the cluster.cluster.localor custom.Next Steps
Thanks for your understanding and contribution.
fix(vm-instance): supply cloud-init network-data to netplan guests (#…