grpc/grpc-go · error

spiffe: BundleMapFromBytes() failed to parse bundle for…

Error message

spiffe: BundleMapFromBytes() failed to parse bundle for trust domain %q: %v

What it means

Raised when spiffebundle.Parse fails for an individual trust domain's bundle JSON inside the Bundle Map. The trust domain key was valid, but the bundle value is not a conformant SPIFFE Bundle (missing x509_authorities, malformed certificates, bad JWT keys, or wrong structure).

Solutions

  1. Fetch the bundle for the named trust domain directly from its SPIFFE Bundle Endpoint and diff it against your input.
  2. Verify each x509_authorities entry is valid PEM/base64 DER that x509.ParseCertificate accepts.
  3. Confirm the bundle JSON includes the required fields per the SPIFFE Bundle spec (e.g. `x509_authorities`, `sequence_number`).
  4. If the corruption is from transport, re-fetch over a trusted channel and store atomically.

Example fix

// before
{"trust_domains": {"example.org": {"x509_authorities": ["not-a-cert"]}}}
// after
{"trust_domains": {"example.org": {"x509_authorities": [{"X509": "<base64 DER>"}], "sequence_number": 1}}}
Defensive patterns

Strategy: try-catch

Validate before calling

func preCheckBundles(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, raw := range probe.TD {
        var bundle struct{ X509 []json.RawMessage `json:"x509_authorities"` }
        if err := json.Unmarshal(raw, &bundle); err != nil { return fmt.Errorf("bundle %s: %w", td, err) }
        if len(bundle.X509) == 0 { return fmt.Errorf("bundle %s: no x509_authorities", td) }
    }
    return nil
}

Try / catch

Wrap BundleMapFromBytes in a recover/error-return; on failure, identify the offending trust domain from the error text and re-fetch just that bundle from its endpoint, then retry once.

Prevention

When it happens

Trigger: A bundle value whose `x509_authorities` entries are not valid base64/PEM certificates, a bundle missing the required `keys`/`x509_authorities` fields, or a bundle with an incompatible spec version.

Common situations: Truncated or corrupted bundle bytes from a secret; a producer using a different SPIFFE Bundle revision; base64 encoding vs raw bytes mismatch; expired/rotated bundle not yet propagated.

Understand the failure class

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/a5c3046ee2f0159a. Report an issue: GitHub.

Appendix: source

Thrown at internal/credentials/spiffe/spiffe.go:59

// 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 {
		return nil, fmt.Errorf("spiffe: could not get spiffe ID from peer leaf cert but verification with spiffe trust map was configured: %v", err)
	}

	// 2. Use the trust domain in the peer certificate's SPIFFE ID to lookup

View on GitHub (pinned to 0c51461d27)