seanmonstar/reqwest · error · reqwest::Error
HTTP/3 only supports 'https' or 'h3' schemes, got: {}
Error message
HTTP/3 only supports 'https' or 'h3' schemes, got: {} What it means
Raised by `extract_domain` in the HTTP/3 pool (pool.rs:369-379) when a request URI's scheme is neither `https` nor `h3`. HTTP/3 mandates TLS 1.3 over QUIC, so plaintext schemes are rejected up front before any connection is attempted.
Source
Thrown at src/async_impl/h3_client/pool.rs:374
if let Some(content_length) = self.content_length {
hyper::body::SizeHint::with_exact(content_length)
} else {
hyper::body::SizeHint::default()
}
}
}
pub(crate) fn extract_domain(uri: &mut Uri) -> Result<Key, Error> {
let uri_clone = uri.clone();
match (uri_clone.scheme(), uri_clone.authority()) {
(Some(scheme), Some(auth)) => {
let scheme_str = scheme.as_str();
if scheme_str != "https" && scheme_str != "h3" {
return Err(Error::new(
Kind::Request,
Some(Box::new(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!(
"HTTP/3 only supports 'https' or 'h3' schemes, got: {}",
scheme_str
),
))),
));
}
Ok((scheme.clone(), auth.clone()))
}
_ => Err(Error::new(Kind::Request, None::<Error>)),
}
}
pub(crate) fn domain_as_uri((scheme, auth): Key) -> Uri {
http::uri::Builder::new()
.scheme(scheme)
.authority(auth)
.path_and_query("/")
.build()View on GitHub (pinned to 17e9bcb51c)
Solutions
- Use an `https://` (or `h3://`) URL for any request going through the HTTP/3 client.
- Do not set `.http3_only()` if you need to reach plaintext `http://` endpoints; drop to `.http3_prior_knowledge()` only on known h3 hosts, or use a plain client for http.
- Validate the URL scheme before dispatch when scheme is user-supplied.
Example fix
// before
let client = Client::builder().http3_only().build()?;
let r = client.get("http://api.example.com").send().await?; // rejected
// after
let url = if !url.starts_with("https://") { format!("https://{url}") } else { url };
let r = client.get(url).send().await?; Defensive patterns
Strategy: validation
Validate before calling
fn h3_url_ok(u: &str) -> bool {
u.starts_with("https://") || u.starts_with("h3://")
}
// guard
if !h3_url_ok(&url) { return Err(anyhow!("h3 requires https:// or h3://")); }
Type guard
fn is_h3_bad_scheme(e: &reqwest::Error) -> bool {
e.is_request()
&& e.source().map(|s| s.to_string().contains("HTTP/3 only supports")).unwrap_or(false)
}
Try / catch
let resp = client.get(&url).send().await.map_err(|e| {
if is_h3_bad_scheme(&e) { anyhow::anyhow!("use https:// for h3 client") } else { e.into() }
})?; Prevention
- Normalize all outbound URLs to https:// before sending.
- Avoid .http3_only() unless every target is known to be https+h3.
When it happens
Trigger: Calling an HTTP/3 client (built with the `http3` feature) against a `http://` URL, a `ws://` URL, or any custom scheme like `ftp://`. Also when a request is manually constructed with `Request::builder().uri("http://...")` and dispatched through the h3 service.
Common situations: Developer enables `http3_only()` but still hits `http://` dev URLs (e.g. localhost); configuration loaded scheme dynamically and the http fallback path wasn't wired; mixed redirect chain where a redirect target is `http://`.
Related errors
- error sending request
- URL scheme is not allowed
- error sending request
- builder error
- error following redirect
AI-assisted analysis of seanmonstar/reqwest@17e9bcb51c (2026-08-06).
Data as JSON: /data/errors/23cfb8016bdd1fc9.json.
Report an issue: GitHub.