{"record":{"id":"2c4acca028542480","repo":"tokio-rs/tokio","slug":"a-tokio-1-x-context-was-found-but-it-is-being-shu-2c4acc","errorCode":null,"errorMessage":"A Tokio 1.x context was found, but it is being shutdown.","messagePattern":"A Tokio 1\\.x context was found, but it is being shutdown\\.","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"tokio/src/runtime/io/registration_set.rs","lineNumber":58,"sourceCode":"            registrations: LinkedList::new(),\n            pending_release: Vec::with_capacity(NOTIFY_AFTER),\n        };\n\n        (set, synced)\n    }\n\n    pub(super) fn is_shutdown(&self, synced: &Synced) -> bool {\n        synced.is_shutdown\n    }\n\n    /// Returns `true` if there are registrations that need to be released\n    pub(super) fn needs_release(&self) -> bool {\n        self.num_pending_release.load(Acquire) != 0\n    }\n\n    pub(super) fn allocate(&self, synced: &mut Synced) -> io::Result<Arc<ScheduledIo>> {\n        if synced.is_shutdown {\n            return Err(io::Error::new(\n                io::ErrorKind::Other,\n                crate::util::error::RUNTIME_SHUTTING_DOWN_ERROR,\n            ));\n        }\n\n        let ret = Arc::new(ScheduledIo::default());\n\n        // Push a ref into the list of all resources.\n        synced.registrations.push_front(ret.clone());\n\n        Ok(ret)\n    }\n\n    // Returns `true` if the caller should unblock the I/O driver to purge\n    // registrations pending release.\n    pub(super) fn deregister(&self, synced: &mut Synced, registration: &Arc<ScheduledIo>) -> bool {\n        synced.pending_release.push(registration.clone());\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/tokio-rs/tokio/blob/625954f365727668cb02d04172b34f1149637728/tokio/src/runtime/io/registration_set.rs#L40-L76","documentation":"RegistrationSet::allocate returns this error when synced.is_shutdown is true. Allocation of a new ScheduledIo (the slot tracking readiness/interests for a freshly registered fd) is refused because the driver is already shut down — the resource cannot be tracked.","triggerScenarios":"Registering a new source with the I/O driver (tokio::net::* construction, AsyncFd registration) after driver shutdown was initiated.","commonSituations":"Creating a new TcpStream/UnixListener during runtime teardown; registering AsyncFd from a task running after shutdown started; nested runtimes where the inner driver is dropped first.","solutions":["Construct all needed I/O resources before initiating runtime shutdown.","Guard resource construction behind a check that the runtime/driver is still alive.","Propagate the error rather than retrying — shutdown is terminal.","Restructure so teardown waits for outstanding I/O resources to close."],"exampleFix":"// before\nruntime.enter();\nlet listener = TcpListener::bind(addr).await?; // may hit allocate() during shutdown\n// after\nif runtime.is_shutting_down() { return Err(shutdown()); }\nlet listener = TcpListener::bind(addr).await?;","handlingStrategy":"validation","validationCode":"// Construct all I/O resources up front, before initiating shutdown.\n// If exposing a builder, refuse new resources once shutdown started:\nif shutdown_started.load(Ordering::SeqCst) {\n    return Err(io::Error::new(io::ErrorKind::Other, \"shutting down\"));\n}\nTcpListener::bind(addr).await","typeGuard":null,"tryCatchPattern":"match TcpListener::bind(addr).await {\n    Ok(l) => l,\n    Err(e) if e.to_string().contains(\"shutting down\") => return Err(e),\n    Err(e) => return Err(e),\n}","preventionTips":["Build resources before runtime teardown begins.","Gate resource construction with a shutdown flag.","Treat 'driver shutdown' as terminal — do not retry."],"tags":["runtime","io-driver","registration","shutdown","io-error"],"backgroundTag":null,"analyzedSha":"625954f365727668cb02d04172b34f1149637728","analyzedAt":"2026-08-11T17:46:45.378Z","contentChangedAt":"2026-08-11T17:46:45.378Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}