{"record":{"id":"22fc893dc9727883","repo":"vectordotdev/vector","slug":"unable-to-compute-next-deadline","errorCode":null,"errorMessage":"unable to compute next deadline","messagePattern":"unable to compute next deadline","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/sinks/file/mod.rs","lineNumber":415,"sourceCode":"                Ok(normalized) => Some(path_to_bytes(&normalized)),\n                Err(error) => {\n                    emit!(FilePathOutsideBaseDirError {\n                        path: &rendered_path,\n                        base_dir: confinement.base_dir(),\n                        error,\n                    });\n                    None\n                }\n            }\n        } else {\n            Some(bytes)\n        }\n    }\n\n    fn deadline_at(&self) -> Instant {\n        Instant::now()\n            .checked_add(self.idle_timeout)\n            .expect(\"unable to compute next deadline\")\n    }\n\n    async fn run(&mut self, mut input: BoxStream<'_, Event>) -> crate::Result<()> {\n        loop {\n            tokio::select! {\n                event = input.next() => {\n                    match event {\n                        Some(event) => self.process_event(event).await,\n                        None => {\n                            // If we got `None` - terminate the processing.\n                            debug!(message = \"Receiver exhausted, terminating the processing loop.\");\n\n                            // Close all the open files.\n                            debug!(message = \"Closing all the open files.\");\n                            for (path, file) in self.files.iter_mut() {\n                                if let Err(error) = file.close().await {\n                                    emit!(FileIoError {\n                                        error,","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/sinks/file/mod.rs#L397-L433","documentation":"The file sink schedules idle flush deadlines by adding its idle_timeout Duration to the current Instant. Instant::checked_add returns None on overflow (only possible on platforms with small Instant ranges or absurdly large idle_timeout), and the expect panics 'unable to compute next deadline'.","triggerScenarios":"deadline_at() is invoked with an idle_timeout so large that Instant::now() + idle_timeout overflows the platform's Instant representation.","commonSituations":"Configuration with an enormous idle_timeout (e.g. centuries in human-readable config); exotic platforms with narrow time representations.","solutions":["Set a reasonable idle_timeout value (seconds/minutes) in the file sink config","Use checked_add and handle None by falling back to a far-future instant","Cap idle_timeout at config validation time"],"exampleFix":"// before\nInstant::now().checked_add(self.idle_timeout).expect(\"unable to compute next deadline\")\n// after\nInstant::now().checked_add(self.idle_timeout).unwrap_or_else(Instant::far_future)","handlingStrategy":"fallback","validationCode":"// rust: sanity-check the duration at config load\nassert!(idle_timeout <= Duration::from_secs(30*24*3600), \"idle_timeout too large\");","typeGuard":"fn fits_instant(d: Duration) -> bool { Instant::now().checked_add(d).is_some() }","tryCatchPattern":"let deadline = Instant::now().checked_add(self.idle_timeout).unwrap_or_else(Instant::far_future);","preventionTips":["Cap idle_timeout at config validation","Avoid absurdly large human durations in config","Use checked arithmetic with explicit fallbacks for time math","Test on platforms with narrow Instant ranges"],"tags":["rust","file-sink","timers","configuration"],"backgroundTag":"value-out-of-range","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}