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

  1. Do not set InsecureSkipVerify on the client tls.Config; provide a proper RootCAs pool instead.
  2. If you must skip verification, do not also rely on ValidateAuthority-based authority checks (grpc.WithAuthority).
  3. 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

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

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/7be7d5a149c30cb8. Report an issue: GitHub.