I am attempting to manage my cluster using kubectl, but I keep getting hit with a "x509: certificate signed by unknown authority" error. This started happening right after I updated my cluster certificates or tried connecting from a new workstation. It seems like a TLS handshake failure between my local machine and the API server. Is this an issue with the CA certificate in my kubeconfig file, or is it related to how the server's master node is advertising its address? How can I fix this without using the insecure-skip-tls-verify flag?
3 answers
This error occurs because the kubectl client cannot verify the identity of the Kubernetes API server using the Certificate Authority (CA) data provided in your ~/.aws/config or ~/.kube/config file. Essentially, the certificate presented by the server isn't trusted by your local machine.
To resolve this, you need to ensure the certificate-authority-data field in your kubeconfig file contains the correct base64-encoded CA certificate that matches the one used by the cluster. If you recently rotated your certificates, your local config is likely outdated. You can often refresh this by re-running the credential command for your cloud provider, such as aws eks update-kubeconfig for AWS or gcloud container clusters get-credentials for GCP. This will pull the latest trusted CA into your local environment.
That makes sense for managed services, but I'm running a bare-metal cluster with kubeadm. If I find that my certificate-authority-data is actually correct but I am accessing the API server through a Load Balancer or a custom DNS name that wasn't included in the original Subject Alternative Names (SANs) during the cert generation, will it still throw this specific x509 "unknown authority" error?
In a pinch, many people use --insecure-skip-tls-verify, but this is dangerous because it opens you up to man-in-the-middle attacks. Always try to fix the kubeconfig CA data first.
I agree with Melissa. It's much better to take the ten minutes to fix the CA chain than to compromise your cluster security. I followed Gregory's initial thought and realized my environment variable KUBECONFIG was pointing to an old file—swapping it to the new one fixed the x509 error immediately.
Brandon, you've touched on a classic networking pitfall. While a missing SAN usually throws a "name mismatch" error, it can sometimes present as an unknown authority if the chain can't be validated through the proxy. For kubeadm, you would need to update your ClusterConfiguration to include the extra SANs and then regenerate your API server certificates. This ensures that when kubectl connects via the Load Balancer's IP or DNS, the certificate presented is considered valid and is properly signed by the CA your client already trusts.