ducaale/xh · error
Invalid proxy URL ' ' for protocol
Error message
Invalid proxy URL '{}' for protocol '{}': {} What it means
FromStr for the --proxy CLI argument splits its input into <PROTOCOL>:<PROXY_URL>, then asks reqwest to parse the URL part. When reqwest::Url::try_from fails (relative URL, bad scheme, unparseable characters), this error wraps the raw URL, the protocol key, and reqwest's own parse message.
Solutions
- Include an absolute scheme in the proxy URL, e.g. --proxy http:http://127.0.0.1:8080
- Quote the whole argument in your shell so spaces/special chars survive: --proxy 'all:http://proxy.local:3128'
- Check reqwest's message at the end of the error for the exact parse failure (relative URL without base, invalid port, etc.) and fix that part
Example fix
// before xh --proxy http:127.0.0.1:8080 GET https://example.com // after xh --proxy http:http://127.0.0.1:8080 GET https://example.com
Defensive patterns
Strategy: validation
Validate before calling
fn validate_proxy_arg(arg: &str) -> Result<(), String> {
let (protocol, url) = arg.split_once(':')
.ok_or("must be <PROTOCOL>:<PROXY_URL>")?;
match protocol.to_lowercase().as_str() {
"http" | "https" | "all" => {},
other => return Err(format!("unknown protocol {}", other)),
}
let parsed = reqwest::Url::parse(url).map_err(|e| e.to_string())?;
if parsed.scheme().is_empty() { return Err("missing URL scheme".into()); }
Ok(())
} Type guard
fn is_absolute_url(s: &str) -> bool {
reqwest::Url::parse(s).map(|u| u.has_host()).unwrap_or(false)
} Try / catch
match ProxyArg::from_str(&arg) {
Ok(p) => p,
Err(e) => eprintln!("--proxy rejected: {e}; expected <PROTOCOL>:<SCHEME>://host:port"),
} Prevention
- Always include an absolute scheme (http:// or https://) in the proxy URL
- Quote the whole --proxy value in your shell
- Remember the key must be http, https, or all
When it happens
Trigger: Passing --proxy http:localhost:8080 (no scheme) or --proxy all:ht tp://bad url or any PROXY_URL that reqwest cannot parse into an absolute URL.
Common situations: Typos in the proxy address, forgetting the http(s):// scheme, quoting problems in shell where spaces or colons break the argument, copy-pasting a proxy string like host:port without a URL scheme.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Unknown protocol to set a proxy for
- The value passed to --proxy should be formatted as
- Value should be formatted as
- is not a supported encoding, please refer to…
- message-signature: RSA private keys require an explicit…
AI-assisted analysis of ducaale/xh@2404aceecc (2026-09-13).
Data as JSON: /api/errors/66f0cce644031b44.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli.rs:1231
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Proxy {
Http(Url),
Https(Url),
All(Url),
}
impl FromStr for Proxy {
type Err = anyhow::Error;
fn from_str(s: &str) -> anyhow::Result<Self> {
let split_arg: Vec<&str> = s.splitn(2, ':').collect();
match split_arg[..] {
[protocol, url] => {
let url = reqwest::Url::try_from(url).map_err(|e| {
anyhow!(
"Invalid proxy URL '{}' for protocol '{}': {}",
url,
protocol,
e
)
})?;
match protocol.to_lowercase().as_str() {
"http" => Ok(Proxy::Http(url)),
"https" => Ok(Proxy::Https(url)),
"all" => Ok(Proxy::All(url)),
_ => Err(anyhow!("Unknown protocol to set a proxy for: {}", protocol)),
}
}
_ => Err(anyhow!(
"The value passed to --proxy should be formatted as <PROTOCOL>:<PROXY_URL>"
)),
}View on GitHub (pinned to 2404aceecc)