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 signed by unknown authority

Before this line, kubectl 1.37 also logs the failed API discovery request as an error-level line containing "Couldn't get current server API group list" and the same TLS error. When the kubeconfig's CA has the same name as the real one, the text continues with "(possibly because of … while trying to verify candidate authority certificate \"kubernetes\")".

kubectl (client-go) — the API server's certificate does not chain to the kubeconfig's certificate-authority-data

What it means

kubectl verifies the API server's certificate against the cluster CA stored in your kubeconfig (certificate-authority or certificate-authority-data), not against the system's public roots. "Unknown authority" means the served certificate does not chain to that CA: the kubeconfig has no CA or a CA of another cluster, or something between you and the API server presents its own certificate.

Why it happens

How to fix it

  1. 1.

    Look at the CA and server in your kubeconfig

    Decode certificate-authority-data and compare its subject and dates with the issuer of the API server's certificate.

    bash
    kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' \
      | base64 -d | openssl x509 -noout -subject -enddate
    kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'
  2. 2.

    Embed the right cluster CA

    Set the cluster entry with the cluster's CA (for kubeadm, /etc/kubernetes/pki/ca.crt) and embed it into the kubeconfig.

    bash
    # kubeadm clusters: the cluster CA is /etc/kubernetes/pki/ca.crt on a control-plane node
    kubectl config set-cluster my-cluster --server=https://k8s.example.com:6443 \
      --certificate-authority=ca.crt --embed-certs=true
  3. 3.

    Regenerate kubeconfig for managed clusters

    The cloud CLIs write a fresh cluster entry with the current endpoint and CA.

    bash
    # Managed clusters: regenerate the kubeconfig entry from the provider
    aws eks update-kubeconfig --name my-cluster --region eu-central-1
    gcloud container clusters get-credentials my-cluster --region europe-west1
    az aks get-credentials --resource-group rg --name my-cluster
  4. 4.

    Bypass the proxy for the API server

    Add the API server's host or network to NO_PROXY instead of disabling TLS verification (insecure-skip-tls-verify).

    bash
    # kubectl honours HTTPS_PROXY; exclude the API server so a TLS-inspecting proxy is bypassed
    export NO_PROXY=k8s.example.com,10.0.0.0/8

Related errors

Browse the full signature error database