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

  1. Verify both files exist, are readable, and are valid PEM (openssl x509 / openssl rsa on each).
  2. Confirm cert and key are a matching pair (compare modulus/public key hashes).
  3. Fix the --client-cert/--client-key paths or re-mount the correct secret.
  4. 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

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


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/663fd4286aaf55ca. Report an issue: GitHub.