{"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":"reqwest::Error","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/17e9bcb51c46edebfb6f5f2f5184b51dac4b3a7d/src/error.rs#L370-L406","documentation":"The `BadScheme` source wrapped in `Kind::Builder` via `error::url_bad_scheme` (error.rs:387-389). It means the URL's scheme is not acceptable: anything other than `http`/`https` for a normal client, or anything other than `https` when the client is https-only. Constructed in `IntoUrl` (into_url.rs:37), at request dispatch (client.rs:2623/2628), and during redirects (redirect.rs:321/326).","triggerScenarios":"Passing `file:///...`, `ftp://`, `ws://`, `data:`, or a scheme-less string like `example.com`; an https-only client (`.https_only(true)`) being pointed at `http://`; a redirect target with a non-http scheme.","commonSituations":"Missing `https://` prefix; reading a path that's actually a `file://` URL; localhost dev with `http://` against a production https-only client; redirect to `ftp://` from a misconfigured server.","solutions":["Prefix the URL with `https://` (or `http://` if plaintext is acceptable).","Don't enable `.https_only(true)` if you must reach plaintext hosts.","Validate `url.scheme() == \"http\" || url.scheme() == \"https\"` before calling `.send()`.","For redirects, ensure servers return http(s) `Location` headers."],"exampleFix":"// before\nlet r = client.get(\"file:///etc/hosts\").send().await?; // 'URL scheme is not allowed'\n\n// after\nlet raw = \"example.com/api\";\nlet url = if raw.starts_with(\"http://\") || raw.starts_with(\"https://\") {\n    raw.to_string()\n} else {\n    format!(\"https://{raw}\")\n};\nlet r = client.get(url).send().await?;","handlingStrategy":"validation","validationCode":"fn ensure_http_scheme(raw: &str) -> anyhow::Result<String> {\n    let u = url::Url::parse(raw).map_err(|e| anyhow!(\"bad url: {e}\"))?;\n    match u.scheme() {\n        \"http\" | \"https\" => Ok(raw.to_string()),\n        _ => Err(anyhow!(\"scheme '{}' not allowed\", u.scheme())),\n    }\n}\n","typeGuard":"fn is_bad_scheme(e: &reqwest::Error) -> bool {\n    e.is_builder() && e.source().map(|s| s.to_string() == \"URL scheme is not allowed\").unwrap_or(false)\n}\n","tryCatchPattern":"let url = ensure_http_scheme(&raw)?;\nlet resp = client.get(url).send().await?;","preventionTips":["Always prefix URLs with https:// at the boundary where they enter your system.","Don't enable https_only unless every target is https.","Reject file://, ftp://, data: at validation time, never let them reach the client."],"tags":["url","scheme","builder","validation"],"analyzedSha":"17e9bcb51c46edebfb6f5f2f5184b51dac4b3a7d","analyzedAt":"2026-08-06T01:23:05.134Z","schemaVersion":2}