kubernetes/kops · critical
error reading certificate %q: %v
Error message
error reading certificate %q: %v
What it means
The kube-apiserver-healthcheck sidecar fails in run() when os.ReadFile cannot read the CA certificate file given by --ca-cert. Without the CA bundle the healthcheck cannot build its x509 root pool to trust the API server. The check aborts before serving health endpoints.
Source
Thrown at cmd/kube-apiserver-healthcheck/main.go:156
flag.StringVar(&clientCert, "client-cert", clientCert, "path to client certificate")
flag.StringVar(&clientKey, "client-key", clientKey, "path to client key")
flag.StringVar(&caCert, "ca-cert", caCert, "path to ca certificate")
klog.InitFlags(nil)
// Opt into the new klog behavior so that -stderrthreshold is honored even
// when -logtostderr=true (the default).
// Ref: kubernetes/klog#212, kubernetes/klog#432
flag.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck
flag.Set("stderrthreshold", "INFO") //nolint:errcheck
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,
}View on GitHub (pinned to 4c8573c808)
Solutions
- Verify the CA cert file exists and is readable at the given path (ls -l / cat the file).
- Fix the --ca-cert flag or the secret volumeMount in the pod manifest.
- Ensure the secret containing the CA exists in the pod's namespace.
- Restart the sidecar after the volume is mounted, or add an init wait for the file.
Example fix
// before
run("--ca-cert", "/etc/missing/ca.crt", ...)
// after
run("--ca-cert", "/etc/kubernetes/pki/ca.crt", ...) Defensive patterns
Strategy: validation
Validate before calling
// before starting the healthcheck
if _, err := os.Stat(caCertPath); err != nil {
return fmt.Errorf("CA cert unavailable at %s: %w", caCertPath, err)
}
if _, err := os.ReadFile(caCertPath); err != nil {
return err
} Try / catch
// Go: wrap and fail fast at startup
if err := run(); err != nil {
klog.Fatalf("healthcheck terminated: %v", err)
} Prevention
- Mount CA secrets as volumes and verify volumeMount paths in the pod spec.
- Validate flag paths with an init container or startup preflight.
- Keep cert paths versioned with the manifest, not hardcoded guesses.
- Set readiness probes so the sidecar restarts if certs vanish.
When it happens
Trigger: The path in --ca-cert does not exist, is unreadable (permissions), is a dangling symlink/misconfigured mount, or the secret volume is not yet mounted when the sidecar starts.
Common situations: Kubernetes secret volume not mounted into the sidecar pod; wrong path flag; file deleted or permissions changed by a security policy; manifest templating error leaving a placeholder path.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- decoding pem public key
- parsing key: %v
- error reading client keypair: %v
- error building kubelet server cert: %v
- signer certificate is required
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/2c8ec677a0e874cb.
Report an issue: GitHub.