{"record":{"id":"04b44addcc75edbc","repo":"tokio-rs/tokio","slug":"a-tokio-1-x-context-was-found-but-io-is-disabled","errorCode":null,"errorMessage":"A Tokio 1.x context was found, but IO is disabled. Call `enable_io` on the runtime builder to enable IO.","messagePattern":"A Tokio 1\\.x context was found, but IO is disabled\\. Call `enable_io` on the runtime builder to enable IO\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"tokio/src/runtime/driver.rs","lineNumber":94,"sourceCode":"    }\n}\n\nimpl Handle {\n    pub(crate) fn unpark(&self) {\n        #[cfg(feature = \"time\")]\n        if let Some(handle) = &self.time {\n            handle.unpark();\n        }\n\n        self.io.unpark();\n    }\n\n    cfg_io_driver! {\n        #[track_caller]\n        pub(crate) fn io(&self) -> &crate::runtime::io::Handle {\n            self.io\n                .as_ref()\n                .expect(\"A Tokio 1.x context was found, but IO is disabled. Call `enable_io` on the runtime builder to enable IO.\")\n        }\n    }\n\n    cfg_signal_internal_and_unix! {\n        #[track_caller]\n        pub(crate) fn signal(&self) -> &crate::runtime::signal::Handle {\n            self.signal\n                .as_ref()\n                .expect(\"A Tokio 1.x context was found, but IO is disabled. Call `enable_io` on the runtime builder to enable IO.\")\n        }\n    }\n\n    cfg_time! {\n        /// Returns a reference to the time driver handle.\n        ///\n        /// Panics if no time driver is present.\n        #[track_caller]\n        pub(crate) fn time(&self) -> &crate::runtime::time::Handle {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/tokio-rs/tokio/blob/7d0d729d8f03a0033d6752730d0fb5928962560e/tokio/src/runtime/driver.rs#L76-L112","documentation":"Driver::io() calls .expect(...) when self.io is None. It panics because the runtime was built with the I/O driver disabled (no enable_io / not enable_all), yet code requested I/O driver access (tokio::net, AsyncFd, etc.).","triggerScenarios":"Using TcpStream/UnixListener/AsyncFd on a runtime built via Builder without enable_io(); e.g. Builder::new_current_thread().enable_time().build() then performing networking.","commonSituations":"Custom Builder config forgetting enable_all; intentionally disabling IO for a CPU-only runtime then accidentally using a net API; test runtime missing IO.","solutions":["Call .enable_all() on the Builder (or .enable_io() explicitly).","If using #[tokio::main], the default flavor already enables IO — don't pass a custom Builder that drops it.","Audit all Builder chains for enable_io/enable_time/enable_signal.","Isolate pure-compute tasks on a time-only runtime and run net code on a full runtime."],"exampleFix":"// before\nlet rt = Builder::new_current_thread().enable_time().build()?;\nrt.block_on(async { TcpStream::connect(...).await.unwrap(); }); // panics\n// after\nlet rt = Builder::new_current_thread().enable_all().build()?;\nrt.block_on(async { TcpStream::connect(...).await.unwrap(); });","handlingStrategy":"validation","validationCode":"// Validate Builder configuration at construction time:\nlet rt = tokio::runtime::Builder::new_current_thread()\n    .enable_all() // ensures IO driver is on\n    .build()?;","typeGuard":null,"tryCatchPattern":"// Panic cannot be caught across the macro; fix the Builder. If you must,\n// catch_unwind around the runtime entry:\nstd::panic::catch_unwind(|| {\n    rt.block_on(async { TcpStream::connect(...).await })\n})","preventionTips":["Always call enable_all() (or enable_io()) on the Builder.","Don't share compute-only runtimes with net code.","Audit every Builder chain for IO/time/signal enablement."],"tags":["runtime","io-driver","builder","panic","configuration"],"backgroundTag":null,"analyzedSha":"7d0d729d8f03a0033d6752730d0fb5928962560e","analyzedAt":"2026-08-11T17:46:45.378Z","contentChangedAt":"2026-08-11T17:46:45.378Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}