grpc/grpc-go · error
xds: fetching identity certificates from…
Error message
xds: fetching identity certificates from CertificateProvider failed: %v
What it means
Raised on the client side during xDS-driven mTLS when hi.identityProvider.KeyMaterial(ctx) returns an error. The identity (client) certificate provider could not return the client cert/key pair the server requires for mutual TLS.
Solutions
- Verify the identity provider config points to valid, readable cert and key files (or the correct xDS resource name).
- Confirm the cert and key match (no rotation half-state) and are valid PEM.
- Ensure the xDS management server advertises an identity CertificateProviderInstance for this client.
- Check the provider is still open and the context is live at handshake time.
- If mTLS is not intended, reconfigure the cluster so the server does not require client certs.
Example fix
// before: identity provider points at /etc/certs/client.crt which is absent // after: provision and mount client.crt + client.key, reload provider
Defensive patterns
Strategy: try-catch
Validate before calling
func identityProviderHealthy(p certprovider.Provider) bool {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
km, err := p.KeyMaterial(ctx)
return err == nil && km != nil && len(km.Certs) > 0
} Try / catch
Treat 'fetching identity certificates failed' as a fatal mTLS setup problem: do not open new RPCs until the provider returns valid KeyMaterial; surface the underlying provider error to the operator.
Prevention
- Provision workload identity cert+key as a mounted secret with atomic rotation.
- Verify cert and key match after each rotation (no half-state).
- Add a readiness probe that calls KeyMaterial before marking the pod ready.
When it happens
Trigger: The identity cert/key files are missing or unreadable; the xDS control plane did not deliver an identity CertificateProviderInstance; the provider was closed; the private key does not match the certificate; the context was cancelled mid-handshake.
Common situations: Workload identity secret not mounted; cert/key rotation left the provider with a half-written file; mTLS required by server (requireClientCert) but client identity not provisioned; provider plugin misconfigured in the bootstrap.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- xds: fetching trusted roots from CertificateProvider failed
- spiffe: could not get spiffe ID from peer leaf cert but…
- xds: no peer certificates presented
- xds: received SANs do not match any of the accepted SANs
- failed to build credentials bundle from bootstrap for
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/6405d99c2fd4d6cd.
Report an issue: GitHub.
Appendix: source
Thrown at internal/credentials/xds/handshake_info.go:242
return nil, fmt.Errorf("xds: fetching trusted roots from CertificateProvider failed: %v", err)
}
cfg.RootCAs = km.Roots
// If AutoHostSNI is true, and the endpoint hostname is present, we use the
// endpoint hostname as the SNI value and also for SAN validation.
// Otherwise, we use the SNI value from HandshakeInfo (which is configured
// by the control plane) and validating SANs based on that.
sni := hi.sni
if hi.useAutoHostSNI && hostname != "" {
sni = hostname
}
cfg.VerifyPeerCertificate = hi.buildVerifyFunc(km, true, sni)
if hi.identityProvider != nil {
km, err := hi.identityProvider.KeyMaterial(ctx)
if err != nil {
return nil, fmt.Errorf("xds: fetching identity certificates from CertificateProvider failed: %v", err)
}
cfg.Certificates = km.Certs
}
if envconfig.XDSSNIEnabled && sni != "" {
cfg.ServerName = sni
}
return cfg, nil
}
func (hi *HandshakeInfo) buildVerifyFunc(km *certprovider.KeyMaterial, isClient bool, sni string) func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
return func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
if len(rawCerts) == 0 {
return fmt.Errorf("xds: no peer certificates presented")
}
// Parse all raw certificates presented by the peer.
var certs []*x509.Certificate
for _, rc := range rawCerts {View on GitHub (pinned to 0c51461d27)