{"record":{"id":"0aa161f6909e964a","repo":"grpc/grpc-go","slug":"xds-certificateprovider-to-fetch-identity-certifi","errorCode":null,"errorMessage":"xds: CertificateProvider to fetch identity certificate is missing, cannot perform TLS handshake. Please check configuration on the management server","messagePattern":"xds: CertificateProvider to fetch identity certificate is missing, cannot perform TLS handshake\\. Please check configuration on the management server","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/credentials/xds/handshake_info.go","lineNumber":334,"sourceCode":"\t\t\t// TODO: Print the complete certificate once the x509 package\n\t\t\t// supports a String() method on the Certificate type.\n\t\t\treturn 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)\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// serverSideTLSConfigInternal constructs a tls.Config to be used in a\n// server-side handshake based on the contents of the HandshakeInfo.\nfunc (hi *HandshakeInfo) serverSideTLSConfigInternal(ctx context.Context) (*tls.Config, error) {\n\tcfg := &tls.Config{\n\t\tClientAuth: tls.NoClientCert,\n\t\tNextProtos: []string{\"h2\"},\n\t}\n\t// On the server side, identityProvider is mandatory. RootProvider is\n\t// optional based on whether the server is doing TLS or mTLS.\n\tif hi.identityProvider == nil {\n\t\treturn nil, errors.New(\"xds: CertificateProvider to fetch identity certificate is missing, cannot perform TLS handshake. Please check configuration on the management server\")\n\t}\n\tif hi.requireClientCert {\n\t\tcfg.ClientAuth = tls.RequireAndVerifyClientCert\n\t}\n\n\t// identityProvider is mandatory on the server side.\n\tkm, err := hi.identityProvider.KeyMaterial(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"xds: fetching identity certificates from CertificateProvider failed: %v\", err)\n\t}\n\tcfg.Certificates = km.Certs\n\n\tif hi.rootProvider != nil {\n\t\tkm, err := hi.rootProvider.KeyMaterial(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"xds: fetching trusted roots from CertificateProvider failed: %v\", err)\n\t\t}\n\t\tif km.SPIFFEBundleMap != nil && hi.requireClientCert {","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/credentials/xds/handshake_info.go#L316-L352","documentation":"Returned by HandshakeInfo.serverSideTLSConfigInternal (internal/credentials/xds/handshake_info.go:334) when hi.identityProvider == nil. On the server side the identity provider (the server's own cert+key to present during the handshake) is mandatory — root provider is optional depending on mTLS. A nil identity provider means the xDS management server's DownstreamTlsContext (server side) did not supply a certificate provider, so the server has nothing to present and cannot complete a TLS handshake.","triggerScenarios":"An xDS-enabled server receives a connection whose UpstreamTlsContext/CommonTlsContext lacks tls_certificates / a default certificate provider. Surfaced at handshake time via ServerSideTLSConfig -> serverSideTLSConfigInternal, returned from ServerHandshake.","commonSituations":"Control plane (Istio/Envoy/Traffic Director) configured root/validation but forgot the server identity cert; cert rotation left a window with no identity provider; the referenced certificate provider instance name does not match any registered plugin; xDS push partially applied.","solutions":["On the management server, ensure the server-side TLS config includes tls_certificates (or a certificate_provider_instance) providing the identity cert+key.","Verify the certprovider plugin named in the config is registered/imported by the server binary.","If mTLS is not required, still provide a server identity cert — the server always needs one for TLS.","Dump the LDS resource for the server listener and confirm the certificate chain is present."],"exampleFix":"// Conceptual: fix is on the xDS control plane.\n// before (server-side UpstreamTlsContext missing tls_certificates)\n// common_tls_context:\n//   validation_context: {...}   # only validation, no identity\n\n// after\n// common_tls_context:\n//   tls_certificates:\n//     - certificate_chain: {filename: \"/etc/grpc/server.pem\"}\n//       private_key:      {filename: \"/etc/grpc/server.key\"}\n//   validation_context: {...}","handlingStrategy":"validation","validationCode":"// Server-side: ensure the certprovider plugin is imported so identity certs\n// can be provided, and verify the control plane ships tls_certificates.\n// import _ \"google.golang.org/grpc/credentials/tls/certprovider/pemfile\"\n// No pure-client validation can create the missing identity; it must be fixed\n// on the management server.","typeGuard":null,"tryCatchPattern":"// On the server, a missing identity provider fails inbound handshakes.\n// Detect by logging and alert on the sentinel; restart after control-plane fix.\nif err != nil && strings.Contains(err.Error(), \"CertificateProvider to fetch identity certificate is missing\") {\n    alertOps(\"xDS control plane missing server identity cert\")\n}","preventionTips":["Always configure server identity certs (tls_certificates) in the xDS UpstreamTlsContext.","Import required certprovider plugins via blank imports.","Test cert rotation in staging to avoid identity-provider gaps."],"tags":["go","grpc","security","xds","tls","handshake","control-plane"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}