{"record":{"id":"3b0a886e966959ec","repo":"slackhq/nebula","slug":"nebula-certificate-for-this-host-is-expired","errorCode":null,"errorMessage":"nebula certificate for this host is expired","messagePattern":"nebula certificate for this host is expired","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pki.go","lineNumber":526,"sourceCode":"\t\t\treturn nil, curve, false, fmt.Errorf(\"unable to read pki.key file %s: %s\", privPathOrPEM, err)\n\t\t}\n\t\trawKey, _, curve, err = cert.UnmarshalPrivateKeyFromPEM(pemPrivateKey)\n\t\tif err != nil {\n\t\t\treturn nil, curve, false, fmt.Errorf(\"error while unmarshaling pki.key %s: %s\", privPathOrPEM, err)\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc loadCertificate(b []byte) (cert.Certificate, []byte, error) {\n\tc, b, err := cert.UnmarshalCertificateFromPEM(b)\n\tif err != nil {\n\t\treturn nil, b, fmt.Errorf(\"error while unmarshaling pki.cert: %w\", err)\n\t}\n\n\tif c.Expired(time.Now()) {\n\t\treturn nil, b, fmt.Errorf(\"nebula certificate for this host is expired\")\n\t}\n\n\tif len(c.Networks()) == 0 {\n\t\treturn nil, b, fmt.Errorf(\"no networks encoded in certificate\")\n\t}\n\n\tif c.IsCA() {\n\t\treturn nil, b, fmt.Errorf(\"host certificate is a CA certificate\")\n\t}\n\n\treturn c, b, nil\n}\n\nfunc loadCAPoolFromConfig(l *slog.Logger, c *config.C) (*cert.CAPool, error) {\n\tcaPathOrPEM := c.GetString(\"pki.ca\", \"\")\n\tif caPathOrPEM == \"\" {\n\t\treturn nil, errors.New(\"no pki.ca path or PEM data provided\")\n\t}","sourceCodeStart":508,"sourceCodeEnd":544,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/pki.go#L508-L544","documentation":"After successfully parsing pki.cert, loadCertificate checks c.Expired(time.Now()); if the certificate's validity window has passed, startup aborts with this error. Nebula refuses to run with an expired host certificate because peers and the CA would reject it anyway.","triggerScenarios":"newCertStateFromConfig loads a host certificate whose NotAfter timestamp is earlier than the current wall-clock time.","commonSituations":"Long-lived deployments where a 1-year (or short-lived) cert aged out; machine clock jumped forward (wrong RTC, VM restore); cert issued with a short expiry for testing.","solutions":["Reissue the host certificate with 'nebula-cert sign' (longer -duration if desired) and update pki.cert","Fix the host clock if it is wrong (NTP sync) and restart","Verify expiry with 'nebula-cert print -path host.crt' before restarting"],"exampleFix":"// before\nnebula-cert sign -ca-cpath ca.crt -ca-kpath ca.key -name host -ip 10.0.0.5  # default short duration\n// after\nnebula-cert sign -ca-cpath ca.crt -ca-kpath ca.key -name host -ip 10.0.0.5 -duration 8760h","handlingStrategy":"validation","validationCode":"c, _, err := cert.UnmarshalCertificateFromPEM(certBytes)\nif err == nil && c.Expired(time.Now()) {\n    return fmt.Errorf(\"host cert expired; reissue before starting\")\n}","typeGuard":"func certValid(c cert.Certificate) bool { return !c.Expired(time.Now()) }","tryCatchPattern":"if err := runNebula(); err != nil && strings.Contains(err.Error(), \"expired\") {\n    if rerr := reissueCert(); rerr != nil { return rerr }\n    return runNebula()\n}","preventionTips":["Monitor cert NotAfter and alert before expiry (e.g. via nebula-cert print in cron)","Issue long-duration certs for stable hosts, short for CI/testing","NTP-sync hosts to avoid false expiry from clock skew","Automate reissue/redeploy of host certs"],"tags":["pki","certificate","expired"],"backgroundTag":"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"}