{"record":{"id":"e0f26ba9cd0783a9","repo":"slackhq/nebula","slug":"no-valid-ca-certificates-present","errorCode":null,"errorMessage":"no valid CA certificates present","messagePattern":"no valid CA certificates present","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pki.go","lineNumber":570,"sourceCode":"\t\tcaReader, err = os.Open(caPathOrPEM)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to read pki.ca file %s: %s\", caPathOrPEM, err)\n\t\t}\n\t}\n\tdefer caReader.Close()\n\n\tcaPool, err := cert.NewCAPoolFromPEMReader(caReader)\n\tif errors.Is(err, cert.ErrExpired) {\n\t\tvar expired int\n\t\tfor _, crt := range caPool.CAs {\n\t\t\tif crt.Certificate.Expired(time.Now()) {\n\t\t\t\texpired++\n\t\t\t\tl.Warn(\"expired certificate present in CA pool\", \"cert\", crt)\n\t\t\t}\n\t\t}\n\n\t\tif expired >= len(caPool.CAs) {\n\t\t\treturn nil, errors.New(\"no valid CA certificates present\")\n\t\t}\n\n\t} else if err != nil {\n\t\treturn nil, fmt.Errorf(\"error while adding CA certificate to CA trust store: %s\", err)\n\t}\n\n\tbl := c.GetStringSlice(\"pki.blocklist\", []string{})\n\tif len(bl) > 0 {\n\t\tfor _, fp := range bl {\n\t\t\tcaPool.BlocklistFingerprint(fp)\n\t\t}\n\n\t\tl.Info(\"Blocklisted certificates\", \"fingerprintCount\", len(bl))\n\t}\n\n\treturn caPool, nil\n}\n","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/pki.go#L552-L588","documentation":"When pki.ca is a bundle containing multiple CAs, loadCAPoolFromConfig counts expired entries; if every CA in the pool is expired, none can anchor trust, so it returns this error. It indicates the CA material loaded successfully but is unusable because it has all expired.","triggerScenarios":"All certificates parsed from pki.ca have NotAfter in the past; expired >= len(caPool.CAs) triggers the error during reloadCAPool.","commonSituations":"Long-lived deployments where the nebula root CA passed its validity window; clock skew making certs appear expired; copying an old ca.crt after rotating CAs; loading an archived/test CA bundle.","solutions":["Re-issue a new CA with nebula-cert ca and re-sign/re-issue host certificates, then update pki.ca.","Check host clock (NTP) to rule out skew causing the expiry check to fail.","Audit CA bundle: remove expired entries and add the current active CA."],"exampleFix":"// regenerate CA and certs\n// before: pki.ca: /etc/nebula/ca.crt (expired)\n// after:  pki.ca: /etc/nebula/ca-new.crt\n$ nebula-cert ca -name \"Nebula CA\" -duration 87600h\n$ nebula-cert sign -ca ca-new.crt -ca-key ca-new.key -name host -out-pub host.crt","handlingStrategy":"validation","validationCode":"pool, err := cert.NewCAPoolFromBytes(caPEM)\nif err != nil && !errors.Is(err, cert.ErrExpired) {\n    return err\n}\nfor _, ca := range pool.CAs {\n    if time.Now().After(ca.Details.NotAfter) {\n        return errors.New(\"CA in pki.ca is expired: rotate the CA\")\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := reloadCAPool(l, c); err != nil {\n    if strings.Contains(err.Error(), \"no valid CA certificates\") {\n        log.Fatal(\"all CAs in pki.ca are expired; issue a new CA and re-sign host certs\")\n    }\n}","preventionTips":["Monitor CA expiry (NotAfter) with alerts well before it lapses","Set long CA durations (e.g. 10y) for internal nebulas and calendar the rotation","Keep clocks synced via NTP so expiry checks are accurate","During CA rotation, include both old and new CAs in pki.ca until all host certs are reissued"],"tags":["pki","ca","expired-certificate","nebula"],"backgroundTag":"ca-certificate-expired","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"}