{"record":{"id":"7be7d5a149c30cb8","repo":"grpc/grpc-go","slug":"credentials-no-peer-certificates-found-to-verify","errorCode":null,"errorMessage":"credentials: no peer certificates found to verify authority %q","messagePattern":"credentials: no peer certificates found to verify authority %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/tls.go","lineNumber":66,"sourceCode":"// AuthType returns the type of TLSInfo as a string.\nfunc (t TLSInfo) AuthType() string {\n\treturn \"tls\"\n}\n\n// ValidateAuthority validates the provided authority being used to override the\n// :authority header by verifying it against the peer certificate. It returns a\n// non-nil error if the validation fails.\nfunc (t TLSInfo) ValidateAuthority(authority string) error {\n\thost, _, err := net.SplitHostPort(authority)\n\tif err != nil {\n\t\thost = authority\n\t}\n\n\t// Verify authority against the leaf certificate.\n\tif len(t.State.PeerCertificates) == 0 {\n\t\t// This is not expected to happen as the TLS handshake has already\n\t\t// completed and should have populated PeerCertificates.\n\t\treturn fmt.Errorf(\"credentials: no peer certificates found to verify authority %q\", host)\n\t}\n\treturn t.State.PeerCertificates[0].VerifyHostname(host)\n}\n\n// cipherSuiteLookup returns the string version of a TLS cipher suite ID.\nfunc cipherSuiteLookup(cipherSuiteID uint16) string {\n\tfor _, s := range tls.CipherSuites() {\n\t\tif s.ID == cipherSuiteID {\n\t\t\treturn s.Name\n\t\t}\n\t}\n\tfor _, s := range tls.InsecureCipherSuites() {\n\t\tif s.ID == cipherSuiteID {\n\t\t\treturn s.Name\n\t\t}\n\t}\n\treturn fmt.Sprintf(\"unknown ID: %v\", cipherSuiteID)\n}","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/tls.go#L48-L84","documentation":"Returned by TLSInfo.ValidateAuthority in credentials/tls.go:66 when the peer certificate slice is empty at the time authority verification is attempted. Normally a completed TLS handshake populates PeerCertificates, so this fires only when the channel was set up with an anonymous/verify-skipping TLS config (e.g. InsecureSkipVerify) or a custom AuthInfo that lacks peer certs.","triggerScenarios":"Calling peer.ValidateAuthority / authority verification on a TLSInfo whose State.PeerCertificates is empty — typically because the tls.Config used InsecureSkipVerify: true or a custom verifier that does not collect the chain.","commonSituations":"Setting InsecureSkipVerify in a tls.Config passed to credentials.NewTLS to bypass cert checks; a custom TransportCredentials that synthesizes TLSInfo without the peer chain; mTLS setups where the client did not present a cert on the server side.","solutions":["Do not set InsecureSkipVerify on the client tls.Config; provide a proper RootCAs pool instead.","If you must skip verification, do not also rely on ValidateAuthority-based authority checks (grpc.WithAuthority).","Ensure the server presents a certificate chain so PeerCertificates is populated."],"exampleFix":"// before\ntlsConf := &tls.Config{InsecureSkipVerify: true}\ncreds := credentials.NewTLS(tlsConf)\nconn, _ := grpc.NewClient(addr, grpc.WithTransportCredentials(creds), grpc.WithAuthority(host))\n\n// after\ntlsConf := &tls.Config{RootCAs: caPool, ServerName: host}\ncreds := credentials.NewTLS(tlsConf)\nconn, _ := grpc.NewClient(addr, grpc.WithTransportCredentials(creds))","handlingStrategy":"validation","validationCode":"// Do not bypass verification on channels that rely on authority checks.\ntlsConf := &tls.Config{RootCAs: caPool, ServerName: host} // no InsecureSkipVerify\ncreds := credentials.NewTLS(tlsConf)\nconn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(creds))","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"no peer certificates found to verify authority\") {\n    // a TLSInfo had no peer certs; remove InsecureSkipVerify or supply RootCAs\n}","preventionTips":["Never set InsecureSkipVerify on a channel that uses grpc.WithAuthority.","Provide RootCAs so the chain is verified and PeerCertificates is populated.","Avoid custom TransportCredentials that synthesize TLSInfo without the peer chain."],"tags":["tls","certificates","validation","authority","go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}