grpc/grpc-go · error
credentials: no peer certificates found to verify authority
Error message
credentials: no peer certificates found to verify authority %q
What it means
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.
Source
Thrown at credentials/tls.go:66
// AuthType returns the type of TLSInfo as a string.
func (t TLSInfo) AuthType() string {
return "tls"
}
// ValidateAuthority validates the provided authority being used to override the
// :authority header by verifying it against the peer certificate. It returns a
// non-nil error if the validation fails.
func (t TLSInfo) ValidateAuthority(authority string) error {
host, _, err := net.SplitHostPort(authority)
if err != nil {
host = authority
}
// Verify authority against the leaf certificate.
if len(t.State.PeerCertificates) == 0 {
// This is not expected to happen as the TLS handshake has already
// completed and should have populated PeerCertificates.
return fmt.Errorf("credentials: no peer certificates found to verify authority %q", host)
}
return t.State.PeerCertificates[0].VerifyHostname(host)
}
// cipherSuiteLookup returns the string version of a TLS cipher suite ID.
func cipherSuiteLookup(cipherSuiteID uint16) string {
for _, s := range tls.CipherSuites() {
if s.ID == cipherSuiteID {
return s.Name
}
}
for _, s := range tls.InsecureCipherSuites() {
if s.ID == cipherSuiteID {
return s.Name
}
}
return fmt.Sprintf("unknown ID: %v", cipherSuiteID)
}View on GitHub (pinned to 03255a9237)
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.
Example fix
// before
tlsConf := &tls.Config{InsecureSkipVerify: true}
creds := credentials.NewTLS(tlsConf)
conn, _ := grpc.NewClient(addr, grpc.WithTransportCredentials(creds), grpc.WithAuthority(host))
// after
tlsConf := &tls.Config{RootCAs: caPool, ServerName: host}
creds := credentials.NewTLS(tlsConf)
conn, _ := grpc.NewClient(addr, grpc.WithTransportCredentials(creds)) Defensive patterns
Strategy: validation
Validate before calling
// Do not bypass verification on channels that rely on authority checks.
tlsConf := &tls.Config{RootCAs: caPool, ServerName: host} // no InsecureSkipVerify
creds := credentials.NewTLS(tlsConf)
conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(creds)) Try / catch
if strings.Contains(err.Error(), "no peer certificates found to verify authority") {
// a TLSInfo had no peer certs; remove InsecureSkipVerify or supply RootCAs
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- ClientConn's authority from transport creds %q and dial opti
- credentials: failed to append certificates
- pemfile: certificate and key file must be in the same direct
- provider instance is closed
- xds: CertificateProvider to fetch trusted roots is missing,
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/7be7d5a149c30cb8.
Report an issue: GitHub.