{"record":{"id":"3e69b7faafa9fe3c","repo":"slackhq/nebula","slug":"errexpired","errorCode":"ErrExpired","errorMessage":"certificate is expired","messagePattern":"certificate is expired","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cert/errors.go","lineNumber":11,"sourceCode":"package cert\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nvar (\n\tErrBadFormat                  = errors.New(\"bad wire format\")\n\tErrRootExpired                = errors.New(\"root certificate is expired\")\n\tErrExpired                    = errors.New(\"certificate is expired\")\n\tErrNotCA                      = errors.New(\"certificate is not a CA\")\n\tErrNotSelfSigned              = errors.New(\"certificate is not self-signed\")\n\tErrBlockListed                = errors.New(\"certificate is in the block list\")\n\tErrFingerprintMismatch        = errors.New(\"certificate fingerprint did not match\")\n\tErrSignatureMismatch          = errors.New(\"certificate signature did not match\")\n\tErrInvalidPublicKey           = errors.New(\"invalid public key\")\n\tErrInvalidPrivateKey          = errors.New(\"invalid private key\")\n\tErrPublicPrivateCurveMismatch = errors.New(\"public key does not match private key curve\")\n\tErrPublicPrivateKeyMismatch   = errors.New(\"public key and private key are not a pair\")\n\tErrPrivateKeyEncrypted        = errors.New(\"private key must be decrypted\")\n\tErrCaNotFound                 = errors.New(\"could not find ca for the certificate\")\n\tErrUnknownVersion             = errors.New(\"certificate version unrecognized\")\n\tErrCertPubkeyPresent          = errors.New(\"certificate has unexpected pubkey present\")\n\tErrCurveMismatch              = errors.New(\"certificate curve does not match CA\")\n\n\tErrInvalidPEMBlock                   = errors.New(\"input did not contain a valid PEM encoded block\")\n\tErrInvalidPEMCertificateBanner       = errors.New(\"bytes did not contain a proper certificate banner\")\n\tErrInvalidPEMX25519PublicKeyBanner   = errors.New(\"bytes did not contain a proper X25519 public key banner\")","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cert/errors.go#L1-L29","documentation":"ErrExpired indicates a CA certificate being loaded or verified has passed its NotAfter time. NewCAPoolFromPEMReader/AddCA tolerate expired CAs (skipping them) but report ErrExpired at the end; verify returns it when the candidate certificate itself is expired.","triggerScenarios":"NewCAPoolFromBytes/FromPEMReader encounters expired CA entries in the PEM (returns pool plus ErrExpired via cert/ca_pool.go:77); pool.AddCA or pool.verify called with an expired certificate; returned from verify when c.Expired(now) is true.","commonSituations":"ca.crt containing stale CAs mixed with valid ones; node left running past the cert's validity window; NTP failure shifting the clock; CI fixtures with hard-coded dates.","solutions":["Replace the expired CA/leaf certificate with one whose NotAfter is in the future.","Check pool.IsExpired / the combined pool+ErrExpired result: the pool is still usable if other CAs are valid; filter or renew expired entries.","Fix clock/NTP sync on the host.","Re-sign the offending certificate from a current CA."],"exampleFix":"// before\npool, err := cert.NewCAPoolFromBytes(caPem)\nif err != nil { return err } // rejects pool even though some CAs are valid\n\n// after\npool, err := cert.NewCAPoolFromBytes(caPem)\nif pool == nil { return err }\nif errors.Is(err, cert.ErrExpired) { log.Warn(\"some CAs expired; renew ca.crt\") }","handlingStrategy":"try-catch","validationCode":"if c.Expired(time.Now()) {\n    log.Warn(\"certificate %s is expired\", c.Name())\n}","typeGuard":"func isCurrent(c cert.Certificate, now time.Time) bool {\n    return !c.Expired(now)\n}","tryCatchPattern":"pool, err := cert.NewCAPoolFromBytes(caPem)\nif pool == nil {\n    return err\n}\nif errors.Is(err, cert.ErrExpired) {\n    log.Warn(\"pool contains expired CAs; renew them\")\n}","preventionTips":["Treat NewCAPoolFromBytes' pool+error combo as partially valid — don't discard the pool when only some CAs expired.","Schedule certificate renewal before NotAfter.","Check host clock/NTP when expiry seems premature."],"tags":["certificate","expiry","pkix"],"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"}