{"record":{"id":"91d74c24e35176b8","repo":"kubernetes/kops","slug":"failed-to-verify-client-certificate-chain-w","errorCode":null,"errorMessage":"failed to verify client certificate chain: %w","messagePattern":"failed to verify client certificate chain: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/pkg/discovery/auth.go","lineNumber":66,"sourceCode":"\n\t\topts := x509.VerifyOptions{\n\t\t\tRoots:         x509.NewCertPool(),\n\t\t\tIntermediates: x509.NewCertPool(),\n\t\t\tKeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},\n\t\t}\n\n\t\tfor i := 1; i < len(peerCertificates); i++ {\n\t\t\tif i == len(peerCertificates)-1 {\n\t\t\t\t// Last cert is the root\n\t\t\t\topts.Roots.AddCert(peerCertificates[i])\n\t\t\t} else {\n\t\t\t\topts.Intermediates.AddCert(peerCertificates[i])\n\t\t\t}\n\t\t}\n\n\t\tchains, err := peerCertificates[0].Verify(opts)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to verify client certificate chain: %w\", err)\n\t\t}\n\t\tverifiedChains = chains\n\t}\n\n\t// The universe ID must match at least one of the certificates in the chain (typically the root CA).\n\tvar matchingChain []*x509.Certificate\n\tfor _, verifiedChain := range verifiedChains {\n\t\tfor _, cert := range verifiedChain {\n\t\t\thash := sha256.Sum256(cert.RawSubjectPublicKeyInfo)\n\t\t\tcalculatedUniverseID := hex.EncodeToString(hash[:])\n\t\t\tif calculatedUniverseID == universeID {\n\t\t\t\tmatchingChain = verifiedChain\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif matchingChain == nil {","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/discovery/pkg/discovery/auth.go#L48-L84","documentation":"AuthenticateClientToUniverse validates an mTLS client certificate against the universe's CA. The certificate chain verification via crypto/x509 Cert.Verify failed, so the client's certificate cannot be trusted as issued by the universe CA. The underlying x509 error (unknown authority, expired, etc.) is wrapped with %w.","triggerScenarios":"Calling AuthenticateClientToUniverse with a TLS peer whose leaf certificate fails x509.Verify: signed by an unknown CA, expired/not-yet-valid, wrong key usage, or intermediates not supplied in peerCertificates.","commonSituations":"Client presents a cert from a different universe/CA than the server trusts; expired client certificate; missing intermediate certs in the TLS handshake; incorrect RootCAs pool loaded in verification opts.","solutions":["Regenerate the client certificate signed by the universe's CA.","Ensure the client sends its full chain (leaf + intermediates) during the TLS handshake.","Check certificate expiry (openssl x509 -noout -dates) and renew if expired.","Confirm the server's trust pool (RootCAs in opts) contains the universe root CA that actually signed the client cert."],"exampleFix":"// before: client presents only the leaf cert\nconn cert = leaf\n// after: client loads the full chain\ntls.LoadX509KeyPair(\"client.crt\", \"client.key\")\ntlsConfig.Certificates[0] = tls.Certificate{Certificate: append([][]byte{leafDER}, intermediates...)}","handlingStrategy":"validation","validationCode":"// verify the client cert before presenting it\nleaf, _ := x509.ParseCertificate(certDER)\nopts := x509.VerifyOptions{Roots: universeCAPool, KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}}\nif _, err := leaf.Verify(opts); err != nil {\n\treturn fmt.Errorf(\"client cert will not verify against universe CA: %w\", err)\n}","typeGuard":"func hasValidClientCert(leaf *x509.Certificate, roots *x509.CertPool) bool {\n\t_, err := leaf.Verify(x509.VerifyOptions{Roots: roots, KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}})\n\treturn err == nil\n}","tryCatchPattern":null,"preventionTips":["Automate client cert rotation before expiry.","Always load the full chain (leaf + intermediates) on the client side.","Keep server trust pool in sync with the universe CA."],"tags":["mtls","tls","certificate-verification","security"],"backgroundTag":"x509-certificate-verification-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}