{"record":{"id":"f97a850abae2bbd0","repo":"seanmonstar/reqwest","slug":"url-scheme-is-not-allowed","errorCode":null,"errorMessage":"URL scheme is not allowed","messagePattern":"URL scheme is not allowed","errorType":"validation","errorClass":"BadScheme","httpStatus":null,"severity":"error","filePath":"src/error.rs","lineNumber":388,"sourceCode":"    status: StatusCode,\n    #[cfg(not(all(target_arch = \"wasm32\", any(target_os = \"unknown\", target_os = \"none\"))))] reason: Option<hyper::ext::ReasonPhrase>,\n) -> Error {\n    Error::new(\n        Kind::Status(\n            status,\n            #[cfg(not(all(\n                target_arch = \"wasm32\",\n                any(target_os = \"unknown\", target_os = \"none\")\n            )))]\n            reason,\n        ),\n        None::<Error>,\n    )\n    .with_url(url)\n}\n\npub(crate) fn url_bad_scheme(url: Url) -> Error {\n    Error::new(Kind::Builder, Some(BadScheme)).with_url(url)\n}\n\npub(crate) fn url_invalid_uri(url: Url) -> Error {\n    Error::new(Kind::Builder, Some(\"Parsed Url is not a valid Uri\")).with_url(url)\n}\n\nif_wasm! {\n    pub(crate) fn wasm(js_val: wasm_bindgen::JsValue) -> BoxError {\n        format!(\"{js_val:?}\").into()\n    }\n}\n\npub(crate) fn upgrade<E: Into<BoxError>>(e: E) -> Error {\n    Error::new(Kind::Upgrade, Some(e))\n}\n\n// io::Error helpers\n","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/seanmonstar/reqwest/blob/9f06fd28abe53e5ff84a091825ea5ce8984b51e0/src/error.rs#L370-L406","documentation":"The BadScheme struct (src/error.rs:432-441) displays as 'URL scheme is not allowed' and is raised by url_bad_scheme() (src/error.rs:387-389) as a Kind::Builder error carrying the offending Url. It is produced at three sites: IntoUrl::into_url() when a parsed Url has no host (src/into_url.rs:34-38), Client::execute_request() when the scheme is not http or https, or when https_only mode rejects an http URL (src/async_impl/client.rs:2622-2629), and the redirect policy when a Location header points to a non-http(s) scheme (src/redirect.rs:320-328). reqwest intentionally restricts transport to http/https; file, ftp, data, blob, ws schemes are rejected.","triggerScenarios":"Calling reqwest::get(\"file:///etc/hosts\"), get(\"data:text/plain,hi\"), get(\"ftp://host\"), get(\"blob:https://...\") (non-wasm), or a bare relative path like get(\"/api/v1\") with no host. Setting .https_only(true) on the builder and then requesting an http:// URL. Following a redirect whose Location is a non-http(s) URI (e.g. a server redirecting to an app:// deep link or data: URI). On non-wasm, passing a host-less Url through IntoUrl.","commonSituations":"Reading a URL from an env var or config file that was set to a file:// path during local dev. Putting a relative path in a base-URL variable. Mixed-content: an https-only client pointed at an http upstream behind a proxy. A server returning a cross-scheme redirect (https -> app deep link). Test fixtures using data: URIs.","solutions":["Use an absolute http:// or https:// URL with a host: prepend the scheme and host to relative paths before calling reqwest.","If you enabled .https_only(true), either disable it or change the target URL to https://.","For file:// resources use std::fs / tokio::fs instead of reqwest; for data: URIs parse them directly.","Configure a redirect::Policy::none() or a custom policy that stops on cross-scheme redirects instead of erroring, if a server may redirect to a non-http(s) Location."],"exampleFix":"// before\nlet resp = reqwest::get(\"/api/v1/users\").await?;\n\n// after\nlet base = std::env::var(\"API_BASE\").unwrap_or_else(|_| \"https://api.example.com\".into());\nlet resp = reqwest::get(format!(\"{base}/api/v1/users\")).await?;","handlingStrategy":"validation","validationCode":"fn validate_reqwest_url(raw: &str) -> Result<url::Url, String> {\n    let url = url::Url::parse(raw).map_err(|e| format!(\"invalid URL: {e}\"))?;\n    if !url.has_host() {\n        return Err(\"URL must have a host\".into());\n    }\n    match url.scheme() {\n        \"http\" | \"https\" => Ok(url),\n        other => Err(format!(\"scheme '{other}' not allowed by reqwest\")),\n    }\n}\n\nlet url = validate_reqwest_url(&raw)?;\nlet resp = reqwest::get(url).await?;","typeGuard":"fn is_transport_scheme(url: &url::Url) -> bool {\n    url.has_host() && matches!(url.scheme(), \"http\" | \"https\")\n}","tryCatchPattern":"match reqwest::get(url).await {\n    Ok(resp) => { /* ... */ }\n    Err(e) => {\n        if e.is_builder()\n            && e.source().map(|s| s.to_string()).as_deref() == Some(\"URL scheme is not allowed\")\n        {\n            // reject the input URL as unsupported transport\n        } else {\n            return Err(e);\n        }\n    }\n}","preventionTips":["Always pass absolute http(s) URLs with a host; reject bare paths at the input boundary.","Keep https_only() consistent with the schemes you actually request.","When following user-controlled redirects, set a custom Policy that rejects cross-scheme Location values up front."],"tags":["url","scheme","builder","redirect","https-only"],"backgroundTag":null,"analyzedSha":"9f06fd28abe53e5ff84a091825ea5ce8984b51e0","analyzedAt":"2026-08-10T17:01:13.368Z","contentChangedAt":"2026-08-10T17:01:13.368Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}