Skip to content
ecdsa.com
kubectl (client-go)Docker and Kubernetes

Error message

Unable to connect to the server: tls: failed to verify certificate: x509: certificate is valid for 10.96.0.1, 192.168.1.10, not 127.0.0.1

The address lists come from your certificate and kubeconfig. For DNS names the message reads "x509: certificate is valid for kubernetes, kubernetes.default, …, not k8s.example.com".

kubectl (client-go) — the API server address in the kubeconfig is not among the API server certificate's SANs

What it means

The API server's certificate is trusted (it chains to the cluster CA), but the address in your kubeconfig's server URL is not one of the names or IPs in its Subject Alternative Names. Go lists the IP SANs it found and the address it wanted. kubeadm issues the API server certificate for the service IP, node addresses and a few DNS names; any other way of reaching it needs an extra SAN.

Why it happens

How to fix it

  1. 1.

    List the certificate's SANs

    Compare them with the server URL in the kubeconfig.

    bash
    # On a control-plane node: the names and addresses the API server certificate covers
    sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -ext subjectAltName
  2. 2.

    Regenerate the API server certificate with extra SANs

    kubeadm init phase certs apiserver issues a new certificate with --apiserver-cert-extra-sans; the old pair must be moved away first, and kube-apiserver restarted to load it.

    bash
    # kubeadm: add the missing address/name to the API server certificate
    sudo mv /etc/kubernetes/pki/apiserver.{crt,key} /root/
    sudo kubeadm init phase certs apiserver --apiserver-cert-extra-sans=203.0.113.20,k8s.example.com
    # then restart the kube-apiserver static pod (e.g. move its manifest out of /etc/kubernetes/manifests and back)
  3. 3.

    Tunnels: set tls-server-name

    kubectl's tls-server-name makes it verify a name the certificate does cover while connecting to the tunnel address, instead of using insecure-skip-tls-verify.

    bash
    # Through a tunnel or port-forward: keep verifying the name the certificate has
    kubectl config set-cluster my-cluster --server=https://127.0.0.1:6443 --tls-server-name=kubernetes

Related errors

Browse the full signature error database