{"record":{"id":"c04a7dc9217a02a3","repo":"slackhq/nebula","slug":"no-issuer-in-certificate","errorCode":null,"errorMessage":"no issuer in certificate","messagePattern":"no issuer in certificate","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cert/ca_pool.go","lineNumber":257,"sourceCode":"\t}\n\tif !c.CheckSignature(signer.Certificate.PublicKey()) {\n\t\treturn nil, ErrSignatureMismatch\n\t}\n\n\terr = CheckCAConstraints(signer.Certificate, c)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn signer, nil\n}\n\n// GetCAForCert attempts to return the signing certificate for the provided certificate.\n// No signature validation is performed\nfunc (ncp *CAPool) GetCAForCert(c Certificate) (*CachedCertificate, error) {\n\tissuer := c.Issuer()\n\tif issuer == \"\" {\n\t\treturn nil, fmt.Errorf(\"no issuer in certificate\")\n\t}\n\n\tsigner, ok := ncp.CAs[issuer]\n\tif ok {\n\t\treturn signer, nil\n\t}\n\n\treturn nil, ErrCaNotFound\n}\n\n// GetFingerprints returns an array of trusted CA fingerprints\nfunc (ncp *CAPool) GetFingerprints() []string {\n\tfp := make([]string, len(ncp.CAs))\n\n\ti := 0\n\tfor k := range ncp.CAs {\n\t\tfp[i] = k\n\t\ti++","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cert/ca_pool.go#L239-L275","documentation":"GetCAForCert looks up the signing CA by the certificate's Issuer field. The library throws \"no issuer in certificate\" when the certificate has an empty issuer, meaning it cannot even attempt the CA lookup. This happens for self-signed/root certificates, which have no issuer recorded (or an issuer that is not the empty string only in the CA map sense).","triggerScenarios":"Calling CAPool.GetCAForCert(c) with a root/CA certificate whose Issuer() returns \"\"; also reached indirectly via CAPool.VerifyCertificate/verify when a root CA certificate is passed in as the certificate being verified.","commonSituations":"Accidentally adding a root CA to the pool as a host cert and then verifying it; calling GetCAForCert on a self-signed certificate generated for testing; parsing an incomplete certificate where the issuer field was never populated.","solutions":["Only pass leaf/intermediate certificates (non-empty Issuer) to GetCAForCert/VerifyCertificate","Check c.Issuer() != \"\" before calling","For self-signed certs, compare fingerprints against the pool's CA entries directly instead","Regenerate the certificate ensuring the issuer field is set by the signing tool"],"exampleFix":"// before\nsigner, err := pool.GetCAForCert(cert) // panics into error for self-signed cert\n// after\nif cert.Issuer() == \"\" {\n    return nil, fmt.Errorf(\"certificate is self-signed; no CA lookup possible\")\n}\nsigner, err := pool.GetCAForCert(cert)","handlingStrategy":"validation","validationCode":"if cert.Issuer() == \"\" {\n    // self-signed or root cert; skip CA lookup\n    return nil\n}\nsigner, err := pool.GetCAForCert(cert)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass root CA certificates into VerifyCertificate/GetCAForCert as the leaf","Check Issuer() before CA lookups","Ensure cert generation tooling populates the issuer field","Distinguish CA certs from host certs in your config loading code"],"tags":["certificate","issuer","ca-lookup"],"backgroundTag":"missing-certificate-issuer","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}