ducaale/xh · error
Value should be formatted as
Error message
Value should be formatted as <HOST>:<ADDRESS> (not <HOST>:<PORT>:<ADDRESS>)
What it means
FromStr for a --resolve-style host/address argument rejects values containing exactly two colons. Since the format is <HOST>:<ADDRESS>, two colons usually mean the user appended a curl-style port (<HOST>:<PORT>:<ADDRESS>) or passed an unbracketed IPv6 address, both ambiguous, so the parser fails fast.
Solutions
- Drop the port segment: pass only <HOST>:<ADDRESS>, e.g. example.com:1.2.3.4
- If you meant an IPv6 address, bracket it so colons stay inside one segment: '[::1]:address' — or use the tool's documented IPv6 syntax
- Combine with the port flag/option of the tool (e.g. put the port in the request URL) instead of baking it into the resolve value
Example fix
// before xh --resolve example.com:443:93.184.216.34 GET https://example.com // after xh --resolve example.com:93.184.216.34 GET https://example.com
Defensive patterns
Strategy: validation
Validate before calling
fn validate_resolve_arg(arg: &str) -> Result<(), String> {
let colons = arg.matches(':').count();
if colons != 1 {
return Err(format!("expected exactly one ':' (got {}); use <HOST>:<ADDRESS>", colons));
}
Ok(())
} Try / catch
match ResolveArg::from_str(&arg) {
Ok(r) => r,
Err(e) if e.to_string().contains("<HOST>:<ADDRESS>") =>
eprintln!("Drop the port segment; put the port in the request URL instead"),
Err(e) => eprintln!("--resolve rejected: {e}"),
} Prevention
- Don't copy curl's HOST:PORT:ADDRESS syntax
- Put the port in the request URL, not the resolve value
- Bracket IPv6 literals if the host can be IPv6
When it happens
Trigger: Passing --resolve example.com:443:1.2.3.4 (curl-style with port) or --resolve example.com:8080:1.2.3.4; also unbracketed IPv6 in the host part.
Common situations: Copying curl's --resolve HOST:PORT:ADDRESS syntax into this tool, or trying to pin an IPv6 host without [brackets].
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- The value passed to --proxy should be formatted as
- Inferred port number in --resolve from request URL.
- Invalid proxy URL ' ' for protocol
- Unknown protocol to set a proxy for
- is not a supported encoding, please refer to…
AI-assisted analysis of ducaale/xh@2404aceecc (2026-09-13).
Data as JSON: /api/errors/958ea6fc304f1927.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli.rs:1266
)),
}
}
}
#[derive(Debug, Clone)]
pub struct Resolve {
pub domain: String,
pub addr: IpAddr,
}
impl FromStr for Resolve {
type Err = anyhow::Error;
fn from_str(s: &str) -> anyhow::Result<Self> {
if s.chars().filter(|&c| c == ':').count() == 2 {
// More than two colons could mean an IPv6 address.
// Exactly two colons probably means the user added a port, curl-style.
return Err(anyhow!(
"Value should be formatted as <HOST>:<ADDRESS> (not <HOST>:<PORT>:<ADDRESS>)"
));
}
let (domain, raw_addr) = s
.split_once(':')
.context("Value should be formatted as <HOST>:<ADDRESS>")?;
let addr = if raw_addr.starts_with('[') && raw_addr.ends_with(']') {
// Support IPv6 addresses enclosed in square brackets e.g. [::1]
Ipv6Addr::from_str(&raw_addr[1..raw_addr.len() - 1]).map(IpAddr::V6)
} else {
raw_addr.parse()
}
.with_context(|| format!("Invalid address '{raw_addr}'"))?;
Ok(Resolve {
domain: domain.to_string(),View on GitHub (pinned to 2404aceecc)