grpc/grpc-go · error
spiffe: BundleMapFromBytes() invalid trust domain
Error message
spiffe: BundleMapFromBytes() invalid trust domain %q found when parsing SPIFFE Bundle Map: %v
What it means
Raised while iterating the parsed `trust_domains` map: a key could not be turned into a SPIFFE trust domain via spiffeid.TrustDomainFromString. Trust domain names must conform to the SPIFFE spec (lowercase RFC 1123 domain label: letters, digits, hyphens, dots per segment; no scheme, no path).
Solutions
- Ensure each trust_domains key is the bare trust domain name (e.g. `example.org`), not a URI.
- Restrict keys to lowercase letters, digits, hyphens, and dots; no underscores, spaces, or slashes.
- Regenerate the bundle map from your SPIFFE federation endpoint so keys match the spec.
- If you control the producer, write keys with spiffeid.TrustDomain.String() to guarantee validity.
Example fix
// before
{"trust_domains": {"spiffe://example.org": {...}}}
// after
{"trust_domains": {"example.org": {...}}} Defensive patterns
Strategy: validation
Validate before calling
var trustDomainRe = regexp.MustCompile(`^[a-z0-9]([a-z0-9\-\.]*[a-z0-9])?$`)
func validTrustDomainKeys(b []byte) error {
var probe struct{ TD map[string]json.RawMessage `json:"trust_domains"` }
if err := json.Unmarshal(b, &probe); err != nil { return err }
for td := range probe.TD {
if !trustDomainRe.MatchString(td) { return fmt.Errorf("bad trust domain key: %q", td) }
}
return nil
} Try / catch
Pre-validate every trust_domains key with spiffeid.TrustDomainFromString before calling BundleMapFromBytes; collect all bad keys in one pass.
Prevention
- Produce trust domain keys via spiffeid.TrustDomain.String() so they are always bare lowercase names.
- Never write a full spiffe:// URI as the map key.
- Review bundle maps produced by third parties for key format.
When it happens
Trigger: A trust_domains key like `spiffe://example.org` (scheme not allowed in a trust domain name), `Example.Org` (uppercase), `my td` (space), `a_b` (underscore), or an empty string.
Common situations: Producer writes the full SPIFFE ID URI as the key instead of the bare trust domain; an upstream system normalizes inconsistently; hand-edited bundle map.
Related errors
- spiffe: BundleMapFromBytes() no bundles parsed from spiffe…
- invalid spiffeid
- spiffe: BundleMapFromBytes() failed to parse bundle for…
- input cert has URIs but should have 1
- input cert is nil
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/6dc4f0e44e08d403.
Report an issue: GitHub.
Appendix: source
Thrown at internal/credentials/spiffe/spiffe.go:55
// BundleMapFromBytes parses bytes into a SPIFFE Bundle Map. See the
// SPIFFE Bundle Map spec for more detail -
// https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE_Trust_Domain_and_Bundle.md#4-spiffe-bundle-format
// If duplicate keys are encountered in the JSON parsing, Go's default unmarshal
// behavior occurs which causes the last processed entry to be the entry in the
// parsed map.
func BundleMapFromBytes(bundleMapBytes []byte) (map[string]*spiffebundle.Bundle, error) {
var result partialParsedSPIFFEBundleMap
if err := json.Unmarshal(bundleMapBytes, &result); err != nil {
return nil, err
}
if result.Bundles == nil {
return nil, fmt.Errorf("spiffe: BundleMapFromBytes() no bundles parsed from spiffe bundle map bytes")
}
bundleMap := map[string]*spiffebundle.Bundle{}
for td, jsonBundle := range result.Bundles {
trustDomain, err := spiffeid.TrustDomainFromString(td)
if err != nil {
return nil, fmt.Errorf("spiffe: BundleMapFromBytes() invalid trust domain %q found when parsing SPIFFE Bundle Map: %v", td, err)
}
bundle, err := spiffebundle.Parse(trustDomain, jsonBundle)
if err != nil {
return nil, fmt.Errorf("spiffe: BundleMapFromBytes() failed to parse bundle for trust domain %q: %v", td, err)
}
bundleMap[td] = bundle
}
return bundleMap, nil
}
// GetRootsFromSPIFFEBundleMap returns the root trust certificates from the
// SPIFFE bundle map for the given trust domain from the leaf certificate.
func GetRootsFromSPIFFEBundleMap(bundleMap map[string]*spiffebundle.Bundle, leafCert *x509.Certificate) (*x509.CertPool, error) {
// 1. Upon receiving a peer certificate, verify that it is a well-formed SPIFFE
// leaf certificate. In particular, it must have a single URI SAN containing
// a well-formed SPIFFE ID ([SPIFFE ID format]).
spiffeID, err := idFromCert(leafCert)
if err != nil {View on GitHub (pinned to 0c51461d27)