grpc/grpc-go · error
spiffe: verify function has no valid input certificates
Error message
spiffe: verify function has no valid input certificates
What it means
After parsing all raw cert blobs, the SPIFFE verify callback checks that at least one certificate was provided (bundle.go:170-171). If the rawCerts slice is empty — meaning the server sent no certificates during the handshake — verification cannot proceed and this error is returned.
Source
Thrown at internal/xds/bootstrap/tlscreds/bundle.go:171
return errors.New("overriding server name is not supported by xDS client TLS credentials")
}
func (c *reloadingCreds) ServerHandshake(net.Conn) (net.Conn, credentials.AuthInfo, error) {
return nil, nil, errors.New("server handshake is not supported by xDS client TLS credentials")
}
func buildSPIFFEVerifyFunc(spiffeBundleMap map[string]*spiffebundle.Bundle) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
return func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
rawCertList := make([]*x509.Certificate, len(rawCerts))
for i, asn1Data := range rawCerts {
cert, err := x509.ParseCertificate(asn1Data)
if err != nil {
return fmt.Errorf("spiffe: verify function could not parse input certificate: %v", err)
}
rawCertList[i] = cert
}
if len(rawCertList) == 0 {
return fmt.Errorf("spiffe: verify function has no valid input certificates")
}
leafCert := rawCertList[0]
roots, err := spiffe.GetRootsFromSPIFFEBundleMap(spiffeBundleMap, leafCert)
if err != nil {
return err
}
opts := x509.VerifyOptions{
Roots: roots,
CurrentTime: time.Now(),
Intermediates: x509.NewCertPool(),
}
for _, cert := range rawCertList[1:] {
opts.Intermediates.AddCert(cert)
}
// The verified chain is (surprisingly) unused.
if _, err = rawCertList[0].Verify(opts); err != nil {View on GitHub (pinned to 03255a9237)
Solutions
- Ensure the xDS management server is configured to present a server certificate.
- Remove any TLS-terminating intermediary that strips certificates, or configure it to forward the origin cert.
- If SPIFFE is not required, remove spiffe_trust_bundle_map_file from the bootstrap so standard RootCA verification is used instead.
Example fix
# verify the server presents a certificate: # openssl s_client -connect xds-server:443 # should show 'Server certificate' and the chain; # if absent, reconfigure the server's TLS cert
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the server sends at least one certificate.
func ensureServerSendsCert(addr string) error {
conf := &tls.Config{InsecureSkipVerify: true}
conn, err := tls.Dial("tcp", addr, conf)
if err != nil { return err }
defer conn.Close()
if len(conn.ConnectionState().PeerCertificates) == 0 {
return errors.New("server sends no certificate")
}
return nil
} Try / catch
if err := creds.ClientHandshake(ctx, authority, conn); err != nil {
if strings.Contains(err.Error(), "no valid input certificates") {
// server misconfigured: not presenting a cert; escalate
}
return err
} Prevention
- Verify the xDS server is configured to present a server certificate.
- Remove any TLS offloader that strips the certificate from the chain.
- Disable SPIFFE verification if not needed for the deployment.
When it happens
Trigger: The server completed the TLS handshake but provided zero certificates. The verify callback receives an empty rawCerts slice, so rawCertList ends up empty.
Common situations: The xDS server is misconfigured to not send a certificate; a load balancer or TLS offloader in front of the server strips the certificate; an anonymized/TLS-PSK setup that does not use certificates; SPIFFE verification enabled against a non-SPIFFE server.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- spiffe: verify function could not parse input certificate: %
- spiffe: x509 certificate Verify failed: %v
- xds: no peer certificates presented
- xds: received DNS SANs: %v do not match the SNI: %s
- failed to unmarshal config: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/8d3d48b27b0f2ece.
Report an issue: GitHub.