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

  1. Set the certificate's notBefore to be >= the signing CA's notBefore
  2. When signing, use a notBefore of now (or the CA's notBefore if backdating is needed) via SignWith options
  3. 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

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

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/7c684ec03c06998b. Report an issue: GitHub.