grpc/grpc-go · error
input cert has URIs but should have 1
Error message
input cert has %v URIs but should have 1
What it means
Raised by idFromCert when len(cert.URIs) != 1. A conformant SPIFFE leaf certificate must carry exactly one URI SAN holding the SPIFFE ID; zero URIs or two-or-more URIs both violate the spec and are rejected.
Solutions
- Re-issue the certificate so the URI SAN list contains exactly one entry, the spiffe:// URI.
- Move any non-SPIFFE URIs to a different SAN type or a custom extension.
- Confirm the CA (SPIRE/workload registrar) is configured to emit a single URI SAN.
- Inspect with: openssl x509 -text -noout | grep -A2 'URI:'.
Example fix
// before: cert URIs = [spiffe://example.org/svc, https://svc/metrics] // after: cert URIs = [spiffe://example.org/svc]
Defensive patterns
Strategy: type-guard
Validate before calling
func hasOneURISAN(c *x509.Certificate) bool { return c != nil && len(c.URIs) == 1 } Type guard
func isSingleURISpiffeCert(c *x509.Certificate) bool {
return c != nil && len(c.URIs) == 1
} Try / catch
In your verifier, after parsing the leaf, assert len(leaf.URIs)==1; if not, reject with a message naming the actual count before the SPIFFE helper does.
Prevention
- Configure your CA/SPIRE to emit exactly one URI SAN per workload cert.
- Audit issued certs periodically for URI SAN count.
- Keep non-SPIFFE URIs out of workload cert templates.
When it happens
Trigger: A cert with no URI SAN (traditional cert); a cert with two URI SANs (e.g. a spiffe:// URI plus an http:// metadata URI); a cert generator that attaches the SPIFFE ID alongside other URIs.
Common situations: Using a general-purpose CA that adds extra URI SANs; service mesh issuing a cert with both SPIFFE and non-SPIFFE URIs; legacy cert with only DNS SANs presented where SPIFFE verification is configured.
Related errors
- invalid spiffeid
- input cert is nil
- spiffe: BundleMapFromBytes() failed to parse bundle for…
- spiffe: could not get spiffe ID from peer leaf cert but…
- spiffe: BundleMapFromBytes() invalid trust domain
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/cbc8196dd2698c76.
Report an issue: GitHub.
Appendix: source
Thrown at internal/credentials/spiffe/spiffe.go:100
return 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())
}
roots := spiffeBundle.X509Authorities()
rootPool := x509.NewCertPool()
for _, root := range roots {
rootPool.AddCert(root)
}
return rootPool, nil
}
// idFromCert parses the SPIFFE ID from the x509.Certificate. If the certificate
// does not have a valid SPIFFE ID, returns an error.
func idFromCert(cert *x509.Certificate) (*spiffeid.ID, error) {
if cert == nil {
return nil, fmt.Errorf("input cert is nil")
}
// A valid SPIFFE Certificate should have exactly one URI.
if len(cert.URIs) != 1 {
return nil, fmt.Errorf("input cert has %v URIs but should have 1", len(cert.URIs))
}
id, err := spiffeid.FromURI(cert.URIs[0])
if err != nil {
return nil, fmt.Errorf("invalid spiffeid: %v", err)
}
return &id, nil
}
View on GitHub (pinned to 0c51461d27)