{"record":{"id":"abddf0ccf988feb0","repo":"nats-io/nats-server","slug":"invalid-ocsp-nextupdate-is-past-time-s","errorCode":null,"errorMessage":"invalid ocsp NextUpdate, is past time: %s","messagePattern":"invalid ocsp NextUpdate, is past time: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/ocsp.go","lineNumber":989,"sourceCode":"}\n\nfunc ocspStatusString(n int) string {\n\tswitch n {\n\tcase ocsp.Good:\n\t\treturn \"good\"\n\tcase ocsp.Revoked:\n\t\treturn \"revoked\"\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\nfunc validOCSPResponse(r *ocsp.Response) error {\n\t// Time validation not handled by ParseResponse.\n\t// https://tools.ietf.org/html/rfc6960#section-4.2.2.1\n\tif !r.NextUpdate.IsZero() && r.NextUpdate.Before(time.Now()) {\n\t\tt := r.NextUpdate.Format(time.RFC3339Nano)\n\t\treturn fmt.Errorf(\"invalid ocsp NextUpdate, is past time: %s\", t)\n\t}\n\tif r.ThisUpdate.After(time.Now()) {\n\t\tt := r.ThisUpdate.Format(time.RFC3339Nano)\n\t\treturn fmt.Errorf(\"invalid ocsp ThisUpdate, is future time: %s\", t)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":971,"sourceCodeEnd":998,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/ocsp.go#L971-L998","documentation":"validOCSPResponse enforces RFC 6960 freshness: an OCSP response whose NextUpdate timestamp is non-zero and in the past is stale and untrusted, since the responder guarantees validity only until NextUpdate.","triggerScenarios":"validOCSPResponse (called from getStatus/getLocalStatus/getRemoteStatus) receives an ocsp.Response where r.NextUpdate.Before(time.Now()) and NextUpdate is not the zero time.","commonSituations":"Cached OCSP responses kept past their validity window, a responder with very short NextUpdate windows, or clock skew/time drift on the NATS server host.","solutions":["Refresh the OCSP response by re-querying the responder (force cache invalidation)","Verify server clock with NTP: `chronyc tracking` or `timedatectl`","Ask the CA operator to increase responder NextUpdate window if too short"],"exampleFix":"// before: long-lived cached response reused after expiry\nresp := cache.Get(cert)\n// after: check and refetch\nif resp.NextUpdate.Before(time.Now()) { resp = fetchFreshOCSP(cert) }","handlingStrategy":"retry","validationCode":"if !resp.NextUpdate.IsZero() && resp.NextUpdate.Before(time.Now()) { refetchOCSP(cert) }","typeGuard":null,"tryCatchPattern":"resp, err := ocsp.ParseResponse(der, issuer)\nif err != nil { ... }\nif verr := validOCSPResponse(resp); verr != nil {\n    // refetch from responder and retry once\n    resp, err = fetchFresh(cert)\n}","preventionTips":["Run NTP on hosts running NATS","Set cache TTLs below the responder's NextUpdate window","Monitor OCSP response freshness in operations dashboards"],"tags":["ocsp","time-validation","rfc6960","stale-response"],"backgroundTag":"ocsp-response-expired","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}