{"record":{"id":"01c239066f2ee277","repo":"grpc/grpc-go","slug":"input-cert-is-nil","errorCode":null,"errorMessage":"input cert is nil","messagePattern":"input cert is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/credentials/spiffe/spiffe.go","lineNumber":96,"sourceCode":"\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))\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":78,"sourceCodeEnd":108,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/credentials/spiffe/spiffe.go#L78-L108","documentation":"Raised by idFromCert when the *x509.Certificate argument is nil. This is a programming-error guard: the caller passed a nil leaf cert into SPIFFE ID extraction.","triggerScenarios":"Calling idFromCert(nil) directly, or GetRootsFromSPIFFEBundleMap(map, nil) when the verification path handed in a nil leaf because the cert chain was empty or parsing upstream failed silently.","commonSituations":"A custom verification callback that does not guard the leaf before calling these helpers; a test that constructs the call with an uninitialized cert variable; a bug in chain assembly.","solutions":["Guard for a nil leaf certificate before calling idFromCert or GetRootsFromSPIFFEBundleMap.","Trace why the leaf is nil: usually an earlier x509.ParseCertificate failure was swallowed or the rawCerts slice was empty.","Add a unit test asserting the nil-leaf branch returns this exact error."],"exampleFix":"// before\nroots, err := spiffe.GetRootsFromSPIFFEBundleMap(m, leaf) // leaf may be nil\n// after\nif leaf == nil {\n    return nil, errors.New(\"no leaf certificate in chain\")\n}\nroots, err := spiffe.GetRootsFromSPIFFEBundleMap(m, leaf)","handlingStrategy":"type-guard","validationCode":"func safeGetRoots(m map[string]*spiffebundle.Bundle, leaf *x509.Certificate) (*x509.CertPool, error) {\n    if leaf == nil { return nil, errors.New(\"no peer leaf certificate\") }\n    return spiffe.GetRootsFromSPIFFEBundleMap(m, leaf)\n}","typeGuard":"func nonNilCert(c *x509.Certificate) bool { return c != nil }","tryCatchPattern":"Always nil-check the leaf in a custom verifier before delegating to SPIFFE helpers; return a descriptive error instead of letting the helper's guard fire.","preventionTips":["Never assume the TLS stack hands you a non-nil leaf — verify the rawCerts slice length first.","Propagate parse errors from x509.ParseCertificate rather than swallowing them.","Add a test that an empty peer cert chain produces your friendly error."],"tags":["grpc","spiffe","tls","certificates","nil-guard","security"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}