{"record":{"id":"bb4f7b46dbbb31e8","repo":"rwf2/Rocket","slug":"brokenpipe-bb4f7b","errorCode":"BrokenPipe","errorMessage":"I/O driver terminated","messagePattern":"I/O driver terminated","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"warning","filePath":"core/lib/src/listener/cancellable.rs","lineNumber":50,"sourceCode":"\npub trait CancellableExt: Sized {\n    fn cancellable(self, stages: Stages) -> Cancellable<Self> {\n        Cancellable {\n            io: Some(self),\n            state: State::Active,\n            stages,\n        }\n    }\n}\n\nimpl<T> CancellableExt for T { }\n\nfn time_out() -> io::Error {\n    io::Error::new(io::ErrorKind::TimedOut, \"shutdown grace period elapsed\")\n}\n\nfn gone() -> io::Error {\n    io::Error::new(io::ErrorKind::BrokenPipe, \"I/O driver terminated\")\n}\n\nimpl<I: AsyncCancel> Cancellable<I> {\n    pub fn inner(&self) -> Option<&I> {\n        self.io.as_ref()\n    }\n}\n\npub trait AsyncCancel {\n    fn poll_cancel(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>;\n}\n\nimpl<T: AsyncWrite> AsyncCancel for T {\n    fn poll_cancel(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {\n        <T as AsyncWrite>::poll_shutdown(self, cx)\n    }\n}\n","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/rwf2/Rocket/blob/3a54d079aef060a8f732bd04ea54b0581a604087/core/lib/src/listener/cancellable.rs#L32-L68","documentation":"Internal runtime error from Rocket's cancellable I/O (core/lib/src/listener/cancellable.rs): after the async I/O driver (tokio reactor) has terminated during shutdown, any further poll of connection I/O returns io::ErrorKind::BrokenPipe with message 'I/O driver terminated' (the gone() constructor). It is the definitive 'this runtime is gone' signal emitted once shutdown has progressed past the grace stage and resources are being torn down.","triggerScenarios":"Server is shutting down; grace expired; the tokio I/O driver is dropped; code still holding connection futures (e.g. a task blocked on read/write) polls them and receives this error. Also seen when a Rocket server future is dropped while connection tasks are still running.","commonSituations":"Tasks spawned per-connection that outlive the #[launch] runtime (e.g. manually spawned tasks holding request I/O); dropping the Rocket server inside a custom multi-runtime setup; shutdown-time log noise from in-flight requests.","solutions":["Accept it as part of shutdown: ensure connection-scoped tasks are tied to request/shutdown lifetimes so they stop when shutdown begins","Use graceful shutdown signals (Rocket.toml [shutdown] with adequate grace) so connections close before the driver terminates","In custom runtimes, keep the runtime alive until all connection tasks finish (JoinHandle them before dropping)","Filter this message from production alerting — it is expected at process exit"],"exampleFix":"// before: detached task outlives the runtime\ntokio::spawn(async move { loop { socket.read(&mut b).await; } });\n\n// after: tie the task to shutdown\nlet mut shutdown = rocket.shutdown().clone();\ntokio::spawn(async move {\n    tokio::select! {\n        _ = shutdown.notified() => {},\n        _ = socket.read(&mut b) => {},\n    }\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// treat BrokenPipe 'I/O driver terminated' as end-of-life, not an error to propagate\nmatch conn_io.poll() {\n    Err(e) if e.kind() == io::ErrorKind::BrokenPipe\n        && e.to_string().contains(\"driver terminated\") => { info_!(\"runtime gone, stopping\"); return; }\n    other => other,\n}","preventionTips":["Select connection loops against rocket.shutdown().notified() so tasks exit before the driver drops","Never spawn detached I/O tasks that outlive the #[launch] runtime","Suppress alerting on this exact message — it only occurs during teardown"],"tags":["rust","rocket","shutdown","async","runtime","tokio"],"backgroundTag":"async-runtime-terminated","analyzedSha":"3a54d079aef060a8f732bd04ea54b0581a604087","analyzedAt":"2026-08-16T22:01:48.395Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}