Skip to content
ecdsa.com
kubectl and other Go clientsDocker and Kubernetes

Error message

x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")

Also printed as

  • x509: certificate signed by unknown authority (possibly because of "x509: ECDSA verification failure" while trying to verify candidate authority certificate "Example Root CA")

kubectl prints it after "Unable to connect to the server: tls: failed to verify certificate: ". For ECDSA CAs the inner reason reads "x509: ECDSA verification failure" instead of "crypto/rsa: verification error"; the quoted name is the CA's common name.

kubectl and other Go clients — a CA with the right name but the wrong key (e.g. a kubeconfig from before kubeadm reset)

What it means

Go found a CA in your trust configuration whose name matches the issuer of the server's certificate ("kubernetes" in kubeadm clusters), tried it, and the signature did not verify with that CA's key. Two different CAs share the same name: the one in your kubeconfig and the one that actually signed the API server's certificate. This is the classic result of rebuilding a cluster (kubeadm reset and init) while keeping the old ~/.kube/config.

Why it happens

How to fix it

  1. 1.

    Confirm that the CA keys differ

    Equal names with different public-key hashes prove the kubeconfig holds another cluster's CA.

    bash
    # Same name, different key? Compare the public keys of the two CAs
    kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' \
      | base64 -d | openssl x509 -noout -pubkey | openssl sha256
    sudo openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -pubkey | openssl sha256   # on a control-plane node
  2. 2.

    Use the new cluster's kubeconfig

    After kubeadm init, copy /etc/kubernetes/admin.conf (or regenerate user kubeconfigs) so the embedded CA matches the new cluster.

    bash
    # After kubeadm init/reset: replace the old kubeconfig with the new admin.conf
    mkdir -p "$HOME/.kube"
    sudo cp /etc/kubernetes/admin.conf "$HOME/.kube/config"
    sudo chown "$(id -u):$(id -g)" "$HOME/.kube/config"
  3. 3.

    Check which kubeconfig is in effect

    KUBECONFIG may list several files; the first one defining the context wins.

    bash
    # Make sure no other kubeconfig overrides it
    echo "$KUBECONFIG"; kubectl config current-context

Related errors

Browse the full signature error database