seanmonstar/reqwest · error · reqwest::Error
error sending request
Error message
error sending request
What it means
The generic `Kind::Request` error from `error::request(...)` (error.rs:356-358). It is the catch-all 'could not send the request' error, used for both the overall request/client timeout (client.rs:3094/3102 wrap `TimedOut`) and the actual transport failure when polling the hyper service (client.rs:3117).
Source
Thrown at src/error.rs:357
Upgrade,
}
// constructors
pub(crate) fn builder<E: Into<BoxError>>(e: E) -> Error {
Error::new(Kind::Builder, Some(e))
}
pub(crate) fn body<E: Into<BoxError>>(e: E) -> Error {
Error::new(Kind::Body, Some(e))
}
pub(crate) fn decode<E: Into<BoxError>>(e: E) -> Error {
Error::new(Kind::Decode, Some(e))
}
pub(crate) fn request<E: Into<BoxError>>(e: E) -> Error {
Error::new(Kind::Request, Some(e))
}
pub(crate) fn dns<E: Into<BoxError>>(e: E) -> BoxError {
Box::new(DnsError { inner: e.into() })
}
pub(crate) fn redirect<E: Into<BoxError>>(e: E, url: Url) -> Error {
Error::new(Kind::Redirect, Some(e)).with_url(url)
}
pub(crate) fn status_code(
url: Url,
status: StatusCode,
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))] reason: Option<hyper::ext::ReasonPhrase>,
) -> Error {
Error::new(
Kind::Status(
status,View on GitHub (pinned to 17e9bcb51c)
Solutions
- Branch on `e.is_timeout()` vs `e.is_connect()` vs `e.is_dns()` to pick the right recovery.
- For timeouts, raise `.timeout()` or add retry with exponential backoff.
- For DNS/connect, verify the URL, network egress, and TLS roots; print `e.source()` for the hyper/hickory error.
- Use a shorter connect timeout separately from the overall timeout to fail fast on unreachable hosts.
Example fix
// before
let resp = client.get(url).send().await?; // 'error sending request', cause unknown
// after
match client.get(url).send().await {
Ok(r) => Ok(r),
Err(e) => {
if e.is_timeout() { retry(/* ... */).await }
else if e.is_connect() || e.is_dns() { return Err(anyhow!("unreachable: {}", e)); }
else { return Err(e.into()); }
}
} Defensive patterns
Strategy: retry
Validate before calling
// No general pre-check; validate URL + DNS reachability for deterministic cases.
let url = url::Url::parse(&raw)?;
if !matches!(url.scheme(), "http" | "https") { return Err(anyhow!("bad scheme")); }
if let Some(host) = url.host_str() { /* optional DNS probe */ }
Type guard
fn classify(e: &reqwest::Error) -> &'static str {
if e.is_timeout() { "timeout" }
else if e.is_connect() { "connect" }
else if e.is_dns() { "dns" }
else if e.is_request() { "request" }
else { "other" }
}
Try / catch
match client.get(&url).send().await {
Ok(r) => Ok(r),
Err(e) if e.is_timeout() || e.is_connect() => backoff_retry().await,
Err(e) if e.is_dns() => Err(anyhow!("unreachable host")),
Err(e) => Err(e.into()),
} Prevention
- Use separate connect and overall timeouts to fail fast on unreachable hosts.
- Wrap send() in retry with classification, not bare ?.
- Surface e.source() in logs so the hyper/DNS cause is visible.
When it happens
Trigger: Client/per-request timeout elapses before a response begins (client.rs:3094, 3102); hyper fails to connect, DNS fails, TLS handshake fails, connection reset, or the connector returns an error (client.rs:3117).
Common situations: Host unreachable / typo'd domain → DNS error; firewall blocking the port; TLS cert mismatch; `.timeout()` too short so the request never completes; server too slow to respond within the deadline.
Related errors
- error sending request
- request or response body error
- error sending request
- error following redirect
- timeout
AI-assisted analysis of seanmonstar/reqwest@17e9bcb51c (2026-08-06).
Data as JSON: /data/errors/6db236d5cad22c5e.json.
Report an issue: GitHub.