{"record":{"id":"7c684ec03c06998b","repo":"slackhq/nebula","slug":"certificate-is-valid-before-the-signing-certificat","errorCode":null,"errorMessage":"certificate is valid before the signing certificate","messagePattern":"certificate is valid before the signing certificate","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cert/ca_pool.go","lineNumber":295,"sourceCode":"\n\treturn fp\n}\n\n// CheckCAConstraints returns an error if the sub certificate violates constraints present in the signer certificate.\nfunc CheckCAConstraints(signer Certificate, sub Certificate) error {\n\treturn checkCAConstraints(signer, sub.NotBefore(), sub.NotAfter(), sub.Groups(), sub.Networks(), sub.UnsafeNetworks())\n}\n\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 {","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cert/ca_pool.go#L277-L313","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nopts.NotBefore = time.Time{} // zero time, before CA notBefore\nnc, err := ca.SignWith(pubKey, curve, opts) // error\n// after\nopts.NotBefore = time.Now().Add(-5 * time.Minute) // small skew, after CA start\nnc, err := ca.SignWith(pubKey, curve, opts)","handlingStrategy":"validation","validationCode":"if sub.NotBefore().Before(signer.NotBefore()) {\n    return fmt.Errorf(\"cert valid before its CA exists; fix notBefore\")\n}\nerr := pool.CheckCAConstraints(signer, sub)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["certificate","validity","ca-constraints"],"backgroundTag":"certificate-validity-window-mismatch","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"}