grpc/grpc-go · error

xds: received SANs {DNSNames: %v, EmailAddresses: %v, IPAddr

Error message

xds: received SANs {DNSNames: %v, EmailAddresses: %v, IPAddresses: %v, URIs: %v} do not match any of the accepted SANs

What it means

Returned by the peer verifier when MatchingSANExists returns false: none of the leaf cert's SANs (DNSNames, EmailAddresses, IPAddresses, URIs) satisfies any of the SAN matchers configured in the HandshakeInfo. The matchers come from the xDS control plane and encode which SANs the peer is allowed to present; a mismatch means the cert is not the expected identity.

Source

Thrown at internal/credentials/xds/handshake_info.go:318

		// If XDSSNIEnabled and AutoSNISANValidation are both true and the SNI is
		// non-empty, validate only DNS SANs against the SNI. Otherwise, fallback to
		// validating all received SANs against the control plane provided SAN
		// matchers.
		if envconfig.XDSSNIEnabled && hi.validateSANUsingSNI && sni != "" {
			// Verify SAN of leaf certificate with SNI using exact DNS matcher.
			for _, san := range certs[0].DNSNames {
				if dnsMatch(sni, san) {
					return nil
				}
			}
			return fmt.Errorf("xds: received DNS SANs: %v do not match the SNI: %s", certs[0].DNSNames, sni)
		}
		// The SANs sent by the xDS control plane are encoded as SPIFFE IDs. We need to
		// only look at the SANs on the leaf cert.
		if cert := certs[0]; !hi.MatchingSANExists(cert) {
			// TODO: Print the complete certificate once the x509 package
			// supports a String() method on the Certificate type.
			return fmt.Errorf("xds: received SANs {DNSNames: %v, EmailAddresses: %v, IPAddresses: %v, URIs: %v} do not match any of the accepted SANs", cert.DNSNames, cert.EmailAddresses, cert.IPAddresses, cert.URIs)
		}
		return nil
	}
}

// serverSideTLSConfigInternal constructs a tls.Config to be used in a
// server-side handshake based on the contents of the HandshakeInfo.
func (hi *HandshakeInfo) serverSideTLSConfigInternal(ctx context.Context) (*tls.Config, error) {
	cfg := &tls.Config{
		ClientAuth: tls.NoClientCert,
		NextProtos: []string{"h2"},
	}
	// On the server side, identityProvider is mandatory. RootProvider is
	// optional based on whether the server is doing TLS or mTLS.
	if hi.identityProvider == nil {
		return nil, errors.New("xds: CertificateProvider to fetch identity certificate is missing, cannot perform TLS handshake. Please check configuration on the management server")
	}
	if hi.requireClientCert {

View on GitHub (pinned to 03255a9237)

Solutions

  1. Compare the SAN matchers advertised by the xDS management server with the SANs actually on the peer cert.
  2. Re-issue or update the security policy so the matcher set covers the peer's current SAN identity.
  3. If the peer cert identity changed intentionally, push an updated xDS security policy.
  4. Inspect the leaf cert SANs with openssl and the configured matchers via xDS config dump to find the mismatch.
Defensive patterns

Strategy: validation

Try / catch

if err := verifyPeer(rawCerts); err != nil {
    if strings.Contains(err.Error(), "do not match any of the accepted SANs") {
        // dump the leaf SANs and the configured matchers, push updated xDS security policy
    }
}

Prevention

When it happens

Trigger: buildVerifyFunc at handshake_info.go:315. The control plane advertised matchers expecting e.g. spiffe://prod/sa/checkout, but the server presented a cert with DNSNames=[api.local] and no matching URI SAN.

Common situations: Control plane configured with the wrong SAN matchers (typo, stale security policy); server rotated to a new cert with a different identity; cluster migrated between trust domains; matcher format mismatch (string matcher prefix/exact/suffix semantics) between the control plane and the client.

Related errors


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