{"id":"a28553555af33893","repo":"actix/actix-web","slug":"response-payload-io-timed-out","errorCode":null,"errorMessage":"Response Payload IO timed out","messagePattern":"Response Payload IO timed out","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"awc/src/responses/mod.rs","lineNumber":37,"sourceCode":"///\n/// See [`ClientResponse::_timeout`] for reason.\npub(crate) enum ResponseTimeout {\n    Disabled(Option<Pin<Box<Sleep>>>),\n    Enabled(Pin<Box<Sleep>>),\n}\n\nimpl Default for ResponseTimeout {\n    fn default() -> Self {\n        Self::Disabled(None)\n    }\n}\n\nimpl ResponseTimeout {\n    fn poll_timeout(&mut self, cx: &mut Context<'_>) -> Result<(), PayloadError> {\n        match *self {\n            Self::Enabled(ref mut timeout) => {\n                if timeout.as_mut().poll(cx).is_ready() {\n                    Err(PayloadError::Io(io::Error::new(\n                        io::ErrorKind::TimedOut,\n                        \"Response Payload IO timed out\",\n                    )))\n                } else {\n                    Ok(())\n                }\n            }\n            Self::Disabled(_) => Ok(()),\n        }\n    }\n}\n","sourceCodeStart":19,"sourceCodeEnd":49,"githubUrl":"https://github.com/actix/actix-web/blob/937960ca67f20e14ffe2a075bf6d4593502be12c/awc/src/responses/mod.rs#L19-L49","documentation":"PayloadError::Io(io::Error(TimedOut, \"Response Payload IO timed out\")) (mod.rs:37-40) is produced by ResponseTimeout::poll_timeout in awc when the deadline set via ClientResponse::timeout(dur) elapses while the response body is still being streamed. The timeout is disabled by default (ResponseTimeout::default() is Disabled) and only armed by an explicit .timeout() call or a request-level timeout whose Sleep is reused via _timeout. It wraps the body poll with a race against a tokio Sleep.","triggerScenarios":"An awc ClientResponse body read (e.g. .body(), .json(), or manual stream polling) is configured with a timeout and the server delivers body bytes slower than the deadline. poll_timeout (mod.rs:33-47) fires and returns the IO timed-out error.","commonSituations":"Slow upstream server, streaming endpoints with infrequent chunks, a timeout set too low for large payloads, or a server that holds the connection open without sending data.","solutions":["Raise or remove the per-response .timeout(dur) if the body legitimately streams slowly.","Stream the body with explicit chunk handling and backpressure instead of buffering it all under one deadline.","Diagnose the upstream: it may be stalled, rate-limited, or waiting on a slow dependency.","Set the request-level timeout (ClientRequest::timeout) appropriately distinct from the body-read timeout."],"exampleFix":"// before: tight body timeout on a slow stream\nlet body = res.timeout(Duration::from_millis(50)).body().await?;\n\n// after: raise the deadline or stream incrementally\nlet body = res.timeout(Duration::from_secs(30)).body().await?;\n// or stream without a single hard deadline:\n// while let Some(chunk) = res.next().await { ... }","handlingStrategy":"try-catch","validationCode":"// Size the timeout from the expected body size and throughput.\nfn body_timeout(bytes: usize, bytes_per_sec: usize) -> std::time::Duration {\n    std::time::Duration::from_secs((bytes as f64 / bytes_per_sec as f64).ceil() as u64 + 5)\n}","typeGuard":null,"tryCatchPattern":"// Distinguish the awc payload timeout from other IO errors.\nuse actix_http::error::PayloadError;\nmatch res.body().await {\n    Err(PayloadError::Io(e)) if e.kind() == std::io::ErrorKind::TimedOut => {\n        // response body deadline elapsed; retry or fall back\n    }\n    Err(e) => { /* other payload errors */ }\n    Ok(body) => { /* ... */ }\n}","preventionTips":["Only enable .timeout(dur) on the response when you expect a bounded, fast body.","Stream large/slow bodies chunk-by-chunk with their own pacing instead of one hard deadline.","Keep the request-level timeout and the body-read timeout distinct and sensibly sized."],"tags":["awc","http-client","timeout","io"],"analyzedSha":"937960ca67f20e14ffe2a075bf6d4593502be12c","analyzedAt":"2026-08-06T01:15:46.978Z","schemaVersion":2}