The kubeadm join token used to add a node to the cluster is invalid, expired, or was malformed.
Kubeadm uses short-lived tokens (default 24 hours) to allow new nodes to securely join the cluster. If the token has expired, is malformed, or was already used, kubeadm join will fail. This is a security mechanism to prevent unauthorized nodes from joining.
List valid tokens:
kubectl -n kube-system get secrets | grep bootstrap-token
kubectl -n kube-system describe secret bootstrap-token-XXXXXOr use kubeadm:
kubeadm token listCreate a new token on the control plane:
kubeadm token create
# Or create a long-lived token
kubeadm token create --ttl 24hThis outputs the token to use in kubeadm join.
You also need the CA hash:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'For production clusters, consider creating tokens with longer TTL or managing them programmatically. Bootstrap tokens are stored as secrets in kube-system namespace. You can revoke a token by deleting its secret: kubectl delete secret -n kube-system bootstrap-token-XXXXX. For automated node joining, integrate with your infrastructure provisioning system.
On the worker node:
kubeadm join YOUR_CP_IP:6443 --token NEW_TOKEN --discovery-token-ca-cert-hash sha256:HASHEnsure token and hash are correct (no typos).
On the control plane:
kubectl get nodesThe new node should appear and transition to Ready status.