{"record":{"id":"c85c11b26524fe8a","repo":"Y2Z/monolith","slug":"time-went-backwards","errorCode":null,"errorMessage":"Time went backwards","messagePattern":"Time went backwards","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cookies.rs","lineNumber":29,"sourceCode":"    pub name: String,\n    pub value: String,\n}\n\n#[derive(Debug)]\npub enum CookieFileContentsParseError {\n    InvalidHeader,\n}\n\nimpl Cookie {\n    pub fn is_expired(&self) -> bool {\n        if self.expires == 0 {\n            return false; // Session, never expires\n        }\n\n        let start = SystemTime::now();\n        let since_the_epoch = start\n            .duration_since(UNIX_EPOCH)\n            .expect(\"Time went backwards\");\n\n        self.expires < since_the_epoch.as_secs()\n    }\n\n    pub fn matches_url(&self, url: &str) -> bool {\n        match Url::parse(url) {\n            Ok(url) => {\n                // Check protocol scheme\n                match url.scheme() {\n                    \"http\" => {\n                        if self.https_only {\n                            return false;\n                        }\n                    }\n                    \"https\" => {}\n                    _ => {\n                        // Should never match URLs of protocols other than HTTP(S)\n                        return false;","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/Y2Z/monolith/blob/a6fc8d009514b2ea271dda2539f19a1f479ebfab/src/cookies.rs#L11-L47","documentation":"This panic comes from an `.expect()` on `SystemTime::now().duration_since(UNIX_EPOCH)` inside `is_expired` in src/cookies.rs. `duration_since` returns `Err` if the system clock is set before the Unix epoch (1970-01-01), so the library panics instead of guessing an expiry. It means the OS clock is wrong, not that the cookie or session is invalid.","triggerScenarios":"Calling `is_expired` (directly or via cookie/session checks during request handling) while the system clock is set earlier than 1970-01-01T00:00:00Z, so `duration_since(UNIX_EPOCH)` yields `Err(SystemTimeError)`.","commonSituations":"Containers/VMs with no RTC whose clock starts at or before the epoch, bare-metal devices booting with a reset CMOS battery, embedded systems without NTP sync, clock drift after restore from a snapshot.","solutions":["Fix the system clock: enable NTP or systemd-timesyncd so the time is after 1970.","Check container/VM time sync: ensure the host clock is correct and RTC/hwclock is set before running the app.","Patch or wrap `is_expired` to treat `duration_since` failure as 'not expired' (return false) instead of panicking.","File an upstream issue so the library replaces `.expect()` with graceful handling of pre-epoch clocks."],"exampleFix":"// before\nlet since_the_epoch = start\n    .duration_since(UNIX_EPOCH)\n    .expect(\"Time went backwards\");\n// after\nlet since_the_epoch = start\n    .duration_since(UNIX_EPOCH)\n    .unwrap_or_default(); // pre-epoch clock: treat as t=0 (nothing expired)","handlingStrategy":"validation","validationCode":"fn system_clock_is_sane() -> bool {\n    SystemTime::now()\n        .duration_since(UNIX_EPOCH)\n        .map(|d| d.as_secs() > 1_600_000_000) // roughly after Sep 2020\n        .unwrap_or(false)\n}\n// call before request handling; if false, resync clock via NTP","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enable NTP/time sync on hosts, containers and VMs before running the app.","In ephemeral containers, wait for clock sync (or check `timedatectl`) before issuing requests.","Add a startup assertion that the clock is after a plausible recent date.","Wrap library calls that may panic in `std::panic::catch_unwind` for batch resilience."],"tags":["rust","panic","system-time","clock","cookies"],"backgroundTag":"system-clock-before-unix-epoch","analyzedSha":"a6fc8d009514b2ea271dda2539f19a1f479ebfab","analyzedAt":"2026-09-05T20:13:04.517Z","contentChangedAt":"2026-09-05T20:13:04.517Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}