Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

If kubeadm join prints [discovery] Failed to request cluster-info, will try again, the message alone does not identify the cause. kubeadm is trying to reach the Kubernetes API server and read discovery data; the error immediately following the retry message tells you whether to investigate the endpoint, network path, API server, token, permissions, or TLS.

Start by testing the exact control-plane address and port from the joining node. Do not regenerate tokens or disable certificate checks until the nested error points to those issues.

Start with the exact error

Run the join command again with verbose logging to capture the complete failure:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo kubeadm join CONTROL_PLANE_ENDPOINT:6443 
  --token TOKEN 
  --discovery-token-ca-cert-hash sha256:CA_HASH 
  --v=6

Use the same endpoint and credentials as the original command. If a join is already retrying, cancel it and rerun with --v=6. Treat the token as a credential: redact it from screenshots, logs, and support posts.

The retry line is generic. Classify the more specific error after it:

Error or result Likely area Next check
i/o timeout Silent network filtering, bad route, VPN/NAT path, or unresponsive API server Test TCP 6443 from the joining node; inspect routes and firewalls
no route to host Routing, subnet, VPN, or firewall rejection Check ip route and the route to the endpoint
connection refused No listener on that address and port, or active rejection Check the API-server listener and destination address
lookup ... no such host DNS, resolver, or hostname configuration Resolve the hostname from the joining node
403 Forbidden or forbidden ConfigMap Discovery authorization, RBAC, altered discovery configuration, or wrong cluster Inspect the response, cluster identity, and bootstrap access
Invalid or expired token / missing token signature Token validity or token-specific discovery signature Check tokens and generate a fresh join command
x509, certificate-name, or CA-hash error Wrong endpoint, certificate SAN, CA hash, or control-plane identity Verify endpoint and certificate trust; regenerate the command if needed
Missing kubeconfig data or malformed discovery object Incomplete cluster-info data or nonstandard cluster setup Inspect the ConfigMap on the intended cluster

What kubeadm is trying to discover

During token-based discovery, kubeadm contacts the API-server endpoint in the join command and requests the cluster-info ConfigMap in the kube-public namespace. That ConfigMap contains a bootstrap kubeconfig. kubeadm also checks for a JWS signature associated with the supplied bootstrap token. When you provide --discovery-token-ca-cert-hash, kubeadm checks the API server’s CA public key against that hash before proceeding with a TLS-validated request and node bootstrap. The implementation describes these discovery and validation steps in the kubeadm token-discovery code; the supported join options are documented in the kubeadm join reference.

That is why a connectivity failure and an authentication or certificate failure need different repairs. If the joining node cannot establish TCP connectivity to the advertised endpoint, token and CA changes will not fix it. If the API server returns an HTTP status or Kubernetes response, the network path has reached the API; investigate the response, discovery data, authorization, or TLS instead.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check the endpoint and network path from the joining node

The endpoint is the host or address in the join command, conventionally followed by port 6443. That is Kubernetes’ standard API-server port, but deployments can use a custom port or a load balancer in front of the API servers. Check the endpoint in the actual join command rather than assuming the control plane’s node address is the right one. The official kubeadm cluster guide shows the control-plane endpoint and port in the join command.

From the joining node, check hostname resolution and routing:

getent hosts CONTROL_PLANE_HOST
resolvectl query CONTROL_PLANE_HOST 2>/dev/null || true
ip route get CONTROL_PLANE_IP

If the command uses an IP rather than a hostname, the DNS checks do not apply. For a hostname-based endpoint, compare its resolved addresses with the intended control-plane or load-balancer address. Split-horizon DNS, stale records, an unexpected public address on a private network, an /etc/hosts override, or IPv6 resolving before a usable IPv4 route can all send the worker to the wrong place. A name resolving successfully does not prove the address is reachable.

Common endpoint mistakes include using loopback, a private IP unreachable from the worker’s subnet, a stale IP after rebuilding a control plane, a public address that does not route back into the private network, or a pod or Service IP instead of the advertised API endpoint. VPN peers and NAT rules must also route the worker to the intended destination.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Test TCP connectivity to the same host and port that kubeadm uses:

nc -vz -w 5 CONTROL_PLANE_HOST 6443

If nc is unavailable, a Bash TCP check is another option:

timeout 5 bash -c '</dev/tcp/CONTROL_PLANE_HOST/6443' 
  && echo "TCP 6443 reachable" 
  || echo "TCP 6443 unreachable"

Interpret the result as a boundary, not a complete diagnosis: a timeout usually points to a dropped path or nonresponsive destination; refusal usually means the destination was reached but no service accepted the connection, or it was actively rejected. A successful TCP connection means you can move on to API, TLS, token, and authorization checks.

You can also make an unauthenticated diagnostic request:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -kiv --connect-timeout 5 
  https://CONTROL_PLANE_HOST:6443/version

An authentication response still demonstrates that the API endpoint answered. The -k flag disables certificate verification for this diagnostic request only; it is not a permanent fix or a replacement for kubeadm’s CA verification. ping is less useful as a primary test: ICMP may be blocked even when TCP 6443 works, or succeed while the API port is blocked.

Check firewalls, cloud rules, and the API server

The required path is from the joining node, or its subnet, to the advertised API endpoint on TCP 6443 (or the configured port). Check host firewalls as well as provider-level security groups, network security groups, subnet ACLs, cloud firewalls, VPN routes, and load-balancer listeners and target health. Restrict the source to the appropriate worker networks where possible; exposing the API port to the entire internet is not a general remedy. Kubernetes lists TCP 6443 as the standard API-server port in its ports and protocols reference.

On Linux, inspect the relevant firewall configuration without flushing rules:

sudo ufw status verbose 2>/dev/null || true
sudo firewall-cmd --list-all 2>/dev/null || true
sudo nft list ruleset
sudo iptables -L -n -v

If the connection times out, look for silent drops in the route, firewall, security group, ACL, VPN, or NAT path as well as an unavailable server. For connection refused, verify that the endpoint is correct and the API server is listening.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

On the control-plane node, check the standard API port:

sudo ss -lntp | grep ':6443'

A listener should appear on the relevant node address, an all-address binding, or the intended control-plane endpoint. If it does not, inspect the API-server static-pod container and kubelet logs:

sudo crictl ps -a | grep kube-apiserver
sudo journalctl -u kubelet -n 200 --no-pager

To inspect logs for a container ID returned by crictl ps -a, use:

sudo crictl logs CONTAINER_ID

Container runtimes and their tooling vary, so use the equivalent runtime command if the cluster does not use a CRI tool available as crictl. Look for static-pod manifest or API-server flag errors, certificate problems, unavailable etcd, resource exhaustion, or a failed upgrade. A server binding only to localhost will not accept connections addressed to an external interface.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For HA clusters, test the shared endpoint

If the join command advertises a load balancer or virtual IP, test that endpoint from the worker, even if an individual control-plane node responds:

nc -vz -w 5 HA_ENDPOINT 6443
curl -kiv --connect-timeout 5 https://HA_ENDPOINT:6443/version

Check that the load balancer has a listener on the configured port, its targets are healthy, its health checks match the backend protocol and port, and the worker network can route to it. Confirm the endpoint’s certificate covers the hostname and that each backend serves the intended cluster. A healthy individual API-server address does not prove that the shared endpoint or its routing is healthy.

Check the token and generate a fresh join command if indicated

A bootstrap token can be invalid, expired, or missing a valid token-specific signature in discovery data. Expiration depends on how it was created and configured, so check rather than assume:

sudo kubeadm token list

If the token is invalid or expired, generate a fresh join command on the existing control plane:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo kubeadm token create --print-join-command

Run the generated command securely on the joining node, confirming that its endpoint is the one workers can reach. kubeadm’s cluster-creation guide documents the generated join command and token management. Keep the token private: anyone who obtains usable join credentials may be able to authenticate a node for joining.

A fresh token addresses token validity and related signature problems. It does not repair a blocked port, wrong address, broken route, stopped API server, or incorrect DNS result.

Inspect discovery data and authorization

If the API server responds but discovery data appears missing or the response is forbidden, inspect the ConfigMap from the control-plane cluster:

export KUBECONFIG=/etc/kubernetes/admin.conf
kubectl -n kube-public get configmap cluster-info -o yaml
kubectl get --raw 
  '/api/v1/namespaces/kube-public/configmaps/cluster-info'

Confirm that the ConfigMap exists and includes kubeconfig data. For token-based discovery, the expected JWS signature is associated with the token ID; a missing or invalid signature can make that token unusable for discovery. Also confirm that the join command was generated for this cluster, not another control plane or a stale configuration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A 403 Forbidden means the server was reached but denied the request. It can indicate bootstrap-token RBAC or discovery configuration problems, a nonstandard cluster setup, or that the endpoint leads to the wrong cluster. Inspect the full response and cluster configuration. Do not solve it by enabling broad anonymous access or granting unrelated permissions.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Handle TLS and CA-hash errors without weakening trust

The CA hash in a normal join command has the form sha256:<hex-encoded-hash>. It pins the API server’s CA public key during discovery. The safest way to obtain it is to generate the join command on the control plane:

sudo kubeadm token create --print-join-command

If you must calculate the CA public-key hash manually, kubeadm’s documented approach is based on the CA certificate’s public key:

openssl x509 
  -pubkey 
  -in /etc/kubernetes/pki/ca.crt |
openssl rsa -pubin -outform der 2>/dev/null |
openssl dgst -sha256 -hex |
sed 's/^.* //'

A wrong CA hash and a certificate-name mismatch are different failures. If the endpoint uses a hostname that is not in the API-server certificate’s subject alternative names (SANs), changing the hash will not make that hostname valid. Check that the endpoint resolves to the intended cluster and that its certificate is issued for the name or address being used.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The option --discovery-token-unsafe-skip-ca-verification removes CA public-key pinning and weakens the discovery trust model. The kubeadm join reference describes this security trade-off. Do not use it as a routine workaround for a bad hash, wrong endpoint, or untrusted certificate.

Consider versions only after reading the failure

Record the versions on both machines:

kubeadm version -o short
kubelet --version
kubectl version --short 2>/dev/null || kubectl version

Keep kubeadm aligned with the Kubernetes minor version being joined and follow Kubernetes’ supported version-skew policy for kubelet and control-plane components. Do not assume every version mismatch causes this retry message: some mismatches instead appear as preflight, authorization, or later bootstrap errors. The official kubeadm troubleshooting guide documents a historical join-related RBAC compatibility issue, which is a reason to check versions when the error points there—not to treat versions as the default cause.

Worker joins, control-plane joins, and CNI timing

Workers and control-plane nodes both perform discovery. A control-plane join adds other requirements, such as the --control-plane option and, when certificates were uploaded during initialization, the appropriate certificate key. It can also fail later while downloading certificates, creating local control-plane manifests, or joining etcd. A successful worker join therefore does not prove that a control-plane join will succeed; see the join reference for the options and phases.

CNI is generally a later concern. A failure to request cluster-info occurs during control-plane discovery, before ordinary pod-network troubleshooting is the likely next step. Investigate the endpoint and discovery error first; the cluster-creation guide treats network-plugin setup as a subsequent part of cluster setup.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Clean up only if a previous join left partial state

Do not reset a node just because discovery is retrying. First identify the underlying cause and determine whether the earlier attempt changed local state. If a failed attempt left partial kubeadm configuration and you intend to retry from a clean node, kubeadm reset may be appropriate:

sudo kubeadm reset -f

Review its effects for your environment before running it, especially on a node with existing Kubernetes state. Do not indiscriminately delete /etc/kubernetes, CNI state, or firewall rules; those actions can remove needed configuration or create new problems.

Quick troubleshooting reference

Symptom What it suggests Useful next check
Timeout Silent network drop, route/VPN issue, wrong endpoint, or unresponsive API server nc -vz -w 5 ENDPOINT 6443; inspect routes and firewall rules
No route Worker cannot route to the destination or traffic is rejected ip route get CONTROL_PLANE_IP; check VPN and subnet paths
Refused No listener or active rejection at the destination ss -lntp and kube-apiserver container status on the control plane
DNS lookup failure or wrong address Resolver, stale record, split DNS, or host override getent hosts CONTROL_PLANE_HOST
403 or forbidden Discovery authorization/configuration or wrong cluster endpoint Inspect the full response and cluster-info on the intended cluster
Invalid or expired token Token or token-specific signature problem kubeadm token list, then kubeadm token create --print-join-command
CA or certificate failure Incorrect CA pin, endpoint identity, or certificate SAN Regenerate the command and verify the endpoint and certificate identity

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.