{"record":{"id":"6263555ae3f7a098","repo":"grpc/grpc-go","slug":"spiffe-no-bundle-found-for-peer-certificates-trus","errorCode":null,"errorMessage":"spiffe: no bundle found for peer certificates trust domain %q but verification with a SPIFFE trust map was configured","messagePattern":"spiffe: no bundle found for peer certificates trust domain %q but verification with a SPIFFE trust map was configured","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/credentials/spiffe/spiffe.go","lineNumber":82,"sourceCode":"}\n\n// GetRootsFromSPIFFEBundleMap returns the root trust certificates from the\n// SPIFFE bundle map for the given trust domain from the leaf certificate.\nfunc GetRootsFromSPIFFEBundleMap(bundleMap map[string]*spiffebundle.Bundle, leafCert *x509.Certificate) (*x509.CertPool, error) {\n\t// 1. Upon receiving a peer certificate, verify that it is a well-formed SPIFFE\n\t//    leaf certificate.  In particular, it must have a single URI SAN containing\n\t//    a well-formed SPIFFE ID ([SPIFFE ID format]).\n\tspiffeID, err := idFromCert(leafCert)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"spiffe: could not get spiffe ID from peer leaf cert but verification with spiffe trust map was configured: %v\", err)\n\t}\n\n\t// 2. Use the trust domain in the peer certificate's SPIFFE ID to lookup\n\t//    the SPIFFE trust bundle. If the trust domain is not contained in the\n\t//    configured trust map, reject the certificate.\n\tspiffeBundle, ok := bundleMap[spiffeID.TrustDomain().Name()]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"spiffe: no bundle found for peer certificates trust domain %q but verification with a SPIFFE trust map was configured\", spiffeID.TrustDomain().Name())\n\t}\n\troots := spiffeBundle.X509Authorities()\n\trootPool := x509.NewCertPool()\n\tfor _, root := range roots {\n\t\trootPool.AddCert(root)\n\t}\n\treturn rootPool, nil\n}\n\n// idFromCert parses the SPIFFE ID from the x509.Certificate. If the certificate\n// does not have a valid SPIFFE ID, returns an error.\nfunc idFromCert(cert *x509.Certificate) (*spiffeid.ID, error) {\n\tif cert == nil {\n\t\treturn nil, fmt.Errorf(\"input cert is nil\")\n\t}\n\t// A valid SPIFFE Certificate should have exactly one URI.\n\tif len(cert.URIs) != 1 {\n\t\treturn nil, fmt.Errorf(\"input cert has %v URIs but should have 1\", len(cert.URIs))","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/credentials/spiffe/spiffe.go#L64-L100","documentation":"Raised by GetRootsFromSPIFFEBundleMap when the peer's leaf cert had a valid SPIFFE ID but its trust domain is not present as a key in the configured SPIFFE bundle map. The connection is rejected because no trusted roots exist for that trust domain.","triggerScenarios":"A peer presents a cert with SPIFFE ID `spiffe://partner.io/svc` but the bundle map only contains `example.org`. Federation is incomplete: the peer's trust domain was never added.","commonSituations":"Onboarding a new partner trust domain but forgetting to add their bundle to the map; bundle map rotation that dropped a trust domain; environment mismatch (prod map used in staging with different trust domains).","solutions":["Add the missing trust domain's bundle to the SPIFFE Bundle Map sourced from that domain's SPIFFE Bundle Endpoint.","Verify the bundle map loaded at runtime contains the peer's trust domain name as a key.","Confirm the peer is connecting from the trust domain you expect (check its SPIFFE ID) and is not a misconfigured or hostile workload.","After updating the map, ensure it is hot-reloaded by the credential provider rather than cached stale."],"exampleFix":"// before: map = {\"example.org\": bundle}\n// peer cert spiffe ID = spiffe://partner.io/svc -> error\n// after: map = {\"example.org\": bundle, \"partner.io\": partnerBundle}","handlingStrategy":"validation","validationCode":"func bundleMapCovers(bundleMap map[string]*spiffebundle.Bundle, td string) bool {\n    _, ok := bundleMap[td]\n    return ok\n}\n// before GetRootsFromSPIFFEBundleMap, extract peer TD via idFromCert and check coverage","typeGuard":null,"tryCatchPattern":"Treat this error as a federation gap: log the missing trust domain, surface it to operators, and fail the connection closed. Do not retry without updating the map.","preventionTips":["Keep the bundle map in sync with all federated trust domains; automate refresh from each domain's bundle endpoint.","Alert when a connection is rejected for an unknown trust domain so ops can add it deliberately.","Test federation in staging with every partner trust domain present."],"tags":["grpc","spiffe","tls","mtls","federation","security"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}