kubernetes/kops · critical
error reading client keypair: %v
Error message
error reading client keypair: %v
What it means
Thrown in run() when tls.LoadX509KeyPair fails to load or parse the client certificate/key pair configured via --client-cert and --client-key. Either file is missing/unreadable or the pair is malformed or mismatched, so mTLS authentication to the API server cannot be set up.
Source
Thrown at cmd/kube-apiserver-healthcheck/main.go:166
flag.Parse()
tlsConfig := &tls.Config{}
if caCert != "" {
b, err := os.ReadFile(caCert)
if err != nil {
return fmt.Errorf("error reading certificate %q: %v", caCert, err)
}
rootCAs := x509.NewCertPool()
rootCAs.AppendCertsFromPEM(b)
tlsConfig.RootCAs = rootCAs
}
if clientKey != "" {
keypair, err := tls.LoadX509KeyPair(clientCert, clientKey)
if err != nil {
return fmt.Errorf("error reading client keypair: %v", err)
}
tlsConfig.Certificates = []tls.Certificate{keypair}
}
transport := &http.Transport{
TLSClientConfig: tlsConfig,
}
s := &healthCheckServer{
transport: transport,
}
http.HandleFunc("/", s.handler)
klog.Infof("listening on %s", listen)
if err := http.ListenAndServe(listen, nil); err != nil {View on GitHub (pinned to 4c8573c808)
Solutions
- Verify both files exist, are readable, and are valid PEM (openssl x509 / openssl rsa on each).
- Confirm cert and key are a matching pair (compare modulus/public key hashes).
- Fix the --client-cert/--client-key paths or re-mount the correct secret.
- Regenerate the client keypair if rotated or mismatched, then restart the healthcheck.
Example fix
// before (paths swapped)
run("--client-cert", "/pki/client.key", "--client-key", "/pki/client.crt")
// after
run("--client-cert", "/pki/client.crt", "--client-key", "/pki/client.key") Defensive patterns
Strategy: validation
Validate before calling
// preflight: load the pair before handing paths to the server
if _, err := tls.LoadX509KeyPair(clientCertPath, clientKeyPath); err != nil {
return fmt.Errorf("client keypair preflight failed: %w", err)
} Try / catch
// Go: fail fast with context at startup
if err := run(); err != nil {
if strings.Contains(err.Error(), "client keypair") {
klog.Fatalf("TLS client config invalid: %v", err)
}
klog.Fatalf("healthcheck terminated: %v", err)
} Prevention
- Generate cert/key together and rotate them as a pair.
- Verify pairs with `openssl x509 -noout -modulus` vs `openssl rsa -noout -modulus`.
- Double-check --client-cert and --client-key are not swapped.
- Keep PEM files base64-decoded correctly when templating from secrets.
When it happens
Trigger: --client-key set but the cert/key files don't exist or are unreadable; cert and key don't match; files are not valid PEM; key is an unsupported format/encryption.
Common situations: Secrets mounted as separate volumes with one path wrong; expired/rotated certificate with mismatched key; PEM blocks corrupted by secret encoding; typo swapping cert and key flags.
Related errors
- decoding pem public key
- parsing key: %v
- error reading certificate %q: %v
- no client certificate presented
- failed to verify client certificate chain: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/663fd4286aaf55ca.
Report an issue: GitHub.