{"record":{"id":"cbc8196dd2698c76","repo":"grpc/grpc-go","slug":"input-cert-has-v-uris-but-should-have-1","errorCode":null,"errorMessage":"input cert has %v URIs but should have 1","messagePattern":"input cert has (.+?) URIs but should have 1","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/credentials/spiffe/spiffe.go","lineNumber":100,"sourceCode":"\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))\n\t}\n\tid, err := spiffeid.FromURI(cert.URIs[0])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid spiffeid: %v\", err)\n\t}\n\treturn &id, nil\n}\n","sourceCodeStart":82,"sourceCodeEnd":108,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/credentials/spiffe/spiffe.go#L82-L108","documentation":"Returned by idFromCert when the leaf certificate's URI SAN list has a length other than exactly one. SPIFFE X.509 SVID spec mandates a single URI SAN carrying the SPIFFE ID; zero URIs (a non-SPIFFE cert) or more than one (ambiguous identity) both violate the spec and are rejected.","triggerScenarios":"Calling GetRootsFromSPIFFEBundleMap with a cert that has no URI SANs, or a cert into which multiple URIs were stuffed (sometimes done to carry metadata). The check is `if len(cert.URIs) != 1` at spiffe.go:99.","commonSituations":"A cert minted by a generic CA that adds no URI SAN; an experimental cert that embedded multiple spiffe:// URIs; wrong cert passed to a verification routine that expects an SVID.","solutions":["Re-issue the certificate through SPIRE so it carries exactly one spiffe:// URI SAN.","Filter to the correct SVID before verification if your cert store contains multiple certs.","Do not add extra URI SANs for metadata — use SPIFFE tracker entries or a separate extension."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"func certHasExactlyOneURI(c *x509.Certificate) error {\n    if c == nil { return errors.New(\"nil cert\") }\n    if len(c.URIs) != 1 {\n        return fmt.Errorf(\"expected 1 URI SAN, got %d\", len(c.URIs))\n    }\n    return nil\n}","typeGuard":"func hasSingleURISAN(c *x509.Certificate) bool {\n    return c != nil && len(c.URIs) == 1\n}","tryCatchPattern":null,"preventionTips":["Issue SVIDs only through SPIRE so the single-URI-SAN invariant holds.","Never add extra URI SANs for metadata; use other extensions.","Reject multi-URI certs at the issuing CA's policy layer."],"tags":["grpc","spiffe","x509","san","certificate"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}