slackhq/nebula · error
certificate is valid before the signing certificate
Error message
certificate is valid before the signing certificate
What it means
checkCAConstraints requires the certificate's notBefore to be at or after the signing CA's notBefore. This error means the certificate claims to be valid earlier than its issuer existed, which would let it be used before the CA was trustworthy.
Source
Thrown at cert/ca_pool.go:295
return fp
}
// CheckCAConstraints returns an error if the sub certificate violates constraints present in the signer certificate.
func CheckCAConstraints(signer Certificate, sub Certificate) error {
return checkCAConstraints(signer, sub.NotBefore(), sub.NotAfter(), sub.Groups(), sub.Networks(), sub.UnsafeNetworks())
}
// 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 {View on GitHub (pinned to dd8f660c0a)
Solutions
- Set the certificate's notBefore to be >= the signing CA's notBefore
- When signing, use a notBefore of now (or the CA's notBefore if backdating is needed) via SignWith options
- Re-issue the certificate with a corrected validity window
Example fix
// before
opts.NotBefore = time.Time{} // zero time, before CA notBefore
nc, err := ca.SignWith(pubKey, curve, opts) // error
// after
opts.NotBefore = time.Now().Add(-5 * time.Minute) // small skew, after CA start
nc, err := ca.SignWith(pubKey, curve, opts) Defensive patterns
Strategy: validation
Validate before calling
if sub.NotBefore().Before(signer.NotBefore()) {
return fmt.Errorf("cert valid before its CA exists; fix notBefore")
}
err := pool.CheckCAConstraints(signer, sub) Prevention
- Use time.Now() (minus small skew) as notBefore when signing
- Avoid zero-value time.Time in signing options
- Compare validity windows programmatically before issuing
- Keep clock synchronization (NTP) on signing hosts
When it happens
Trigger: Calling CheckCAConstraints(signer, sub) where sub.NotBefore() is before signer.NotBefore(); or SignWith with a notBefore earlier than the CA's start of validity (including backdated certs).
Common situations: Backdating a certificate for clock-skew tolerance more than the CA's own backdating; generating certs with notBefore=time zero; re-signing an old cert whose validity window predates the renewed CA.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- certificate expires after signing certificate
- certificate contained a group not present on the signing ca:
- 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/7c684ec03c06998b.
Report an issue: GitHub.