slackhq/nebula · critical
nebula certificate for this host is expired
Error message
nebula certificate for this host is expired
What it means
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.
Source
Thrown at pki.go:526
return nil, curve, false, fmt.Errorf("unable to read pki.key file %s: %s", privPathOrPEM, err)
}
rawKey, _, curve, err = cert.UnmarshalPrivateKeyFromPEM(pemPrivateKey)
if err != nil {
return nil, curve, false, fmt.Errorf("error while unmarshaling pki.key %s: %s", privPathOrPEM, err)
}
}
return
}
func loadCertificate(b []byte) (cert.Certificate, []byte, error) {
c, b, err := cert.UnmarshalCertificateFromPEM(b)
if err != nil {
return nil, b, fmt.Errorf("error while unmarshaling pki.cert: %w", err)
}
if c.Expired(time.Now()) {
return nil, b, fmt.Errorf("nebula certificate for this host is expired")
}
if len(c.Networks()) == 0 {
return nil, b, fmt.Errorf("no networks encoded in certificate")
}
if c.IsCA() {
return nil, b, fmt.Errorf("host certificate is a CA certificate")
}
return c, b, nil
}
func loadCAPoolFromConfig(l *slog.Logger, c *config.C) (*cert.CAPool, error) {
caPathOrPEM := c.GetString("pki.ca", "")
if caPathOrPEM == "" {
return nil, errors.New("no pki.ca path or PEM data provided")
}View on GitHub (pinned to dd8f660c0a)
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
Example fix
// before nebula-cert sign -ca-cpath ca.crt -ca-kpath ca.key -name host -ip 10.0.0.5 # default short duration // after nebula-cert sign -ca-cpath ca.crt -ca-kpath ca.key -name host -ip 10.0.0.5 -duration 8760h
Defensive patterns
Strategy: validation
Validate before calling
c, _, err := cert.UnmarshalCertificateFromPEM(certBytes)
if err == nil && c.Expired(time.Now()) {
return fmt.Errorf("host cert expired; reissue before starting")
} Type guard
func certValid(c cert.Certificate) bool { return !c.Expired(time.Now()) } Try / catch
if err := runNebula(); err != nil && strings.Contains(err.Error(), "expired") {
if rerr := reissueCert(); rerr != nil { return rerr }
return runNebula()
} Prevention
- 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
When it happens
Trigger: newCertStateFromConfig loads a host certificate whose NotAfter timestamp is earlier than the current wall-clock time.
Common situations: 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.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- no certificates found in pki.cert
- %s: %w
- can not sign a CA certificate with another
- error computing issuer: %v
- self signed certificates must have IsCA set to true
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/3b0a886e966959ec.
Report an issue: GitHub.