{"record":{"id":"6405d99c2fd4d6cd","repo":"grpc/grpc-go","slug":"xds-fetching-identity-certificates-from-certifica","errorCode":null,"errorMessage":"xds: fetching identity certificates from CertificateProvider failed: %v","messagePattern":"xds: fetching identity certificates from CertificateProvider failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/credentials/xds/handshake_info.go","lineNumber":242,"sourceCode":"\t\treturn nil, fmt.Errorf(\"xds: fetching trusted roots from CertificateProvider failed: %v\", err)\n\t}\n\tcfg.RootCAs = km.Roots\n\n\t// If AutoHostSNI is true, and the endpoint hostname is present, we use the\n\t// endpoint hostname as the SNI value and also for SAN validation.\n\t// Otherwise, we use the SNI value from HandshakeInfo (which is configured\n\t// by the control plane) and validating SANs based on that.\n\tsni := hi.sni\n\tif hi.useAutoHostSNI && hostname != \"\" {\n\t\tsni = hostname\n\t}\n\n\tcfg.VerifyPeerCertificate = hi.buildVerifyFunc(km, true, sni)\n\n\tif hi.identityProvider != nil {\n\t\tkm, err := hi.identityProvider.KeyMaterial(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"xds: fetching identity certificates from CertificateProvider failed: %v\", err)\n\t\t}\n\t\tcfg.Certificates = km.Certs\n\t}\n\n\tif envconfig.XDSSNIEnabled && sni != \"\" {\n\t\tcfg.ServerName = sni\n\t}\n\treturn cfg, nil\n}\n\nfunc (hi *HandshakeInfo) buildVerifyFunc(km *certprovider.KeyMaterial, isClient bool, sni string) func(rawCerts [][]byte, _ [][]*x509.Certificate) error {\n\treturn func(rawCerts [][]byte, _ [][]*x509.Certificate) error {\n\t\tif len(rawCerts) == 0 {\n\t\t\treturn fmt.Errorf(\"xds: no peer certificates presented\")\n\t\t}\n\t\t// Parse all raw certificates presented by the peer.\n\t\tvar certs []*x509.Certificate\n\t\tfor _, rc := range rawCerts {","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/credentials/xds/handshake_info.go#L224-L260","documentation":"Returned by the client-side TLS config builder when mTLS is configured (identityProvider is set) and hi.identityProvider.KeyMaterial(ctx) fails. The client cannot present a client certificate, so the mTLS handshake setup is aborted. The wrapped error is from the identity certprovider.","triggerScenarios":"clientSideTLSConfigInternal at handshake_info.go:240, when the identity provider (the one supplying client certs) cannot produce key material — e.g. its cert file is missing or the xDS side has not delivered the identity cert.","commonSituations":"mTLS enabled on the cluster but the identity provider resource is missing from the xDS config; SPIRE/agent not running so no client cert is available; file path misconfigured; cert rotation gap where the old cert was removed before the new arrived.","solutions":["Confirm the identity CertificateProvider resource is configured on the management server for this cluster.","Verify the workload's SPIRE agent is running and has issued a client cert.","Check filesystem paths/permissions for file-based identity providers.","If mTLS is not actually required, drop the identityProvider from HandshakeInfo so the client does TLS instead of mTLS."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, _, _, err := xds.ClientSideTLSConfig(ctx, hi, host); err != nil {\n    if strings.Contains(err.Error(), \"fetching identity certificates\") {\n        // identity provider not ready; retry once xDS delivers the client cert\n    }\n}","preventionTips":["Ensure the client workload has an issued SVID before establishing mTLS channels.","Keep the SPIRE agent healthy so identity material is always available.","Drop the identityProvider if one-way TLS is acceptable."],"tags":["grpc","xds","mtls","cert-provider","handshake","client"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}