slackhq/nebula · error
certificate contained a group not present on the signing ca:
Error message
certificate contained a group not present on the signing ca: %s
What it means
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.
Source
Thrown at cert/ca_pool.go:303
// checkCAConstraints is a very generic function allowing both Certificates and TBSCertificates to be tested.
func checkCAConstraints(signer Certificate, notBefore, notAfter time.Time, groups []string, networks, unsafeNetworks []netip.Prefix) error {
// Make sure this cert isn't valid after the root
if notAfter.After(signer.NotAfter()) {
return fmt.Errorf("certificate expires after signing certificate")
}
// Make sure this cert wasn't valid before the root
if notBefore.Before(signer.NotBefore()) {
return fmt.Errorf("certificate is valid before the signing certificate")
}
// If the signer has a limited set of groups make sure the cert only contains a subset
signerGroups := signer.Groups()
if len(signerGroups) > 0 {
for _, g := range groups {
if !slices.Contains(signerGroups, g) {
return fmt.Errorf("certificate contained a group not present on the signing ca: %s", g)
}
}
}
// If the signer has a limited set of ip ranges to issue from make sure the cert only contains a subset
signingNetworks := signer.Networks()
if len(signingNetworks) > 0 {
for _, certNetwork := range networks {
found := false
for _, signingNetwork := range signingNetworks {
if signingNetwork.Contains(certNetwork.Addr()) && signingNetwork.Bits() <= certNetwork.Bits() {
found = true
break
}
}
if !found {
return fmt.Errorf("certificate contained a network assignment outside the limitations of the signing ca: %s", certNetwork.String())View on GitHub (pinned to dd8f660c0a)
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
Example fix
// before
opts.Groups = []string{"laptop", "servers"} // CA only allows "laptop"
nc, err := ca.SignWith(pubKey, curve, opts)
// after
opts.Groups = intersect(opts.Groups, ca.Groups()) // keep only CA-sanctioned groups
nc, err := ca.SignWith(pubKey, curve, opts) Defensive patterns
Strategy: validation
Validate before calling
signerGroups := signer.Groups()
for _, g := range certGroups {
if !slices.Contains(signerGroups, g) {
return fmt.Errorf("group %q not allowed by CA", g)
}
}
err := pool.CheckCAConstraints(signer, sub) Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- certificate expires after signing certificate
- certificate is valid before the signing certificate
- certificate contained a network assignment outside the limit
- certificate contained an unsafe network assignment outside t
- ErrBadFormat
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/4fead2a59ee05aeb.
Report an issue: GitHub.