{"record":{"id":"4fead2a59ee05aeb","repo":"slackhq/nebula","slug":"certificate-contained-a-group-not-present-on-the-s","errorCode":null,"errorMessage":"certificate contained a group not present on the signing ca: %s","messagePattern":"certificate contained a group not present on the signing ca: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cert/ca_pool.go","lineNumber":303,"sourceCode":"\n// checkCAConstraints is a very generic function allowing both Certificates and TBSCertificates to be tested.\nfunc checkCAConstraints(signer Certificate, notBefore, notAfter time.Time, groups []string, networks, unsafeNetworks []netip.Prefix) error {\n\t// Make sure this cert isn't valid after the root\n\tif notAfter.After(signer.NotAfter()) {\n\t\treturn fmt.Errorf(\"certificate expires after signing certificate\")\n\t}\n\n\t// Make sure this cert wasn't valid before the root\n\tif notBefore.Before(signer.NotBefore()) {\n\t\treturn fmt.Errorf(\"certificate is valid before the signing certificate\")\n\t}\n\n\t// If the signer has a limited set of groups make sure the cert only contains a subset\n\tsignerGroups := signer.Groups()\n\tif len(signerGroups) > 0 {\n\t\tfor _, g := range groups {\n\t\t\tif !slices.Contains(signerGroups, g) {\n\t\t\t\treturn fmt.Errorf(\"certificate contained a group not present on the signing ca: %s\", g)\n\t\t\t}\n\t\t}\n\t}\n\n\t// If the signer has a limited set of ip ranges to issue from make sure the cert only contains a subset\n\tsigningNetworks := signer.Networks()\n\tif len(signingNetworks) > 0 {\n\t\tfor _, certNetwork := range networks {\n\t\t\tfound := false\n\t\t\tfor _, signingNetwork := range signingNetworks {\n\t\t\t\tif signingNetwork.Contains(certNetwork.Addr()) && signingNetwork.Bits() <= certNetwork.Bits() {\n\t\t\t\t\tfound = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !found {\n\t\t\t\treturn fmt.Errorf(\"certificate contained a network assignment outside the limitations of the signing ca: %s\", certNetwork.String())","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cert/ca_pool.go#L285-L321","documentation":"If the signing CA has a non-empty Groups list, any certificate it signs may only contain groups that are a subset of the CA's groups. This error names the offending group found on the certificate but absent from the CA.","triggerScenarios":"CheckCAConstraints(signer, sub) where a group in sub.Groups() is not in signer.Groups(); SignWith whose options request groups outside the CA's allowed set; verify() invoking this after a successful signature check.","commonSituations":"Typo in a group name in the host config vs the CA definition; CA later narrowed its group list while old certs still request removed groups; operator assigns a new group to a host without updating the CA's group allowlist.","solutions":["Remove or correct the offending group so the cert's groups are a subset of the CA's","Add the group to the signing CA's Groups list and re-issue the CA (or use a CA that already includes it)","Sign with a different CA whose group set covers the requested groups"],"exampleFix":"// before\nopts.Groups = []string{\"laptop\", \"servers\"} // CA only allows \"laptop\"\nnc, err := ca.SignWith(pubKey, curve, opts)\n// after\nopts.Groups = intersect(opts.Groups, ca.Groups()) // keep only CA-sanctioned groups\nnc, err := ca.SignWith(pubKey, curve, opts)","handlingStrategy":"validation","validationCode":"signerGroups := signer.Groups()\nfor _, g := range certGroups {\n    if !slices.Contains(signerGroups, g) {\n        return fmt.Errorf(\"group %q not allowed by CA\", g)\n    }\n}\nerr := pool.CheckCAConstraints(signer, sub)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a single source of truth for group definitions shared by CA and host configs","Validate requested groups against the CA before signing","Watch for group-name typos between config files","When narrowing CA groups, re-issue dependent certs"],"tags":["certificate","groups","ca-constraints"],"backgroundTag":"certificate-constraint-violation","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"}