cloudflare/quiche · error
--connect-to is expected to be a string containing an IPv4…
Error message
--connect-to is expected to be a string containing an IPv4 or IPv6 address with a port. E.g. 192.0.2.0:443
What it means
h3i's resolve_socket_addrs parses the --connect-to CLI value with SocketAddr::parse and panics on failure with this message. The value must be a literal 'IP:port' string, not a hostname or a bare URL.
Solutions
- Pass a literal IPv4/IPv6 address with port, e.g. --connect-to 192.0.2.0:443.
- Omit --connect-to so the address is derived from host_port instead.
- Pre-resolve the hostname to an IP with dig/host and use that IP.
Example fix
// before h3i --host_port example.com:443 --connect-to example.com:443 // after h3i --host_port example.com:443 --connect-to 93.184.216.34:443
Defensive patterns
Strategy: validation
Validate before calling
use std::net::SocketAddr;
let addr: SocketAddr = connect_to.parse()
.map_err(|_| "--connect-to must be IP:port, e.g. 192.0.2.0:443")?; Prevention
- Always pass literal IP:port, never hostnames or URLs.
- Resolve hostnames with dig/host before invoking h3i.
- Prefer omitting --connect-to and letting host_port derive the address.
When it happens
Trigger: Passing --connect-to with a hostname (example.com:443), a scheme (https://192.0.2.0:443), a missing port, or malformed IP to h3i (or quiche-client-style tools sharing this code).
Common situations: Copying a hostname into --connect-to when doing SNI/host overriding; forgetting the port; IPv6 literals without brackets are handled, but URLs are not.
Understand the failure class
Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.
Related errors
- unable to parse bind address
- --connect-to is expected to be a string containing an IPv4…
- An error happened when asking for payload, try again later.
- An error happened, stopping.
- invalid CC frame in qlog input, no error code
AI-assisted analysis of cloudflare/quiche@9f96daa2c2 (2026-09-08).
Data as JSON: /api/errors/ffb504359066b66b.
Report an issue: GitHub.
Appendix: source
Thrown at h3i/src/client/mod.rs:574
let connect_url = if !args.omit_sni {
args.host_port.split(':').next()
} else {
None
};
let (peer_addr, bind_addr) = resolve_socket_addrs(args);
ParsedArgs {
peer_addr,
bind_addr,
connect_url,
}
}
fn resolve_socket_addrs(args: &Config) -> (SocketAddr, SocketAddr) {
// Resolve server address.
let peer_addr = if let Some(addr) = &args.connect_to {
addr.parse().expect("--connect-to is expected to be a string containing an IPv4 or IPv6 address with a port. E.g. 192.0.2.0:443")
} else {
let x = format!("https://{}", args.host_port);
*url::Url::parse(&x)
.unwrap()
.socket_addrs(|| None)
.unwrap()
.first()
.unwrap()
};
// Bind to INADDR_ANY or IN6ADDR_ANY depending on the IP family of the
// server address. This is needed on macOS and BSD variants that don't
// support binding to IN6ADDR_ANY for both v4 and v6.
let bind_addr = match peer_addr {
std::net::SocketAddr::V4(_) => format!("0.0.0.0:{}", args.source_port),
std::net::SocketAddr::V6(_) => format!("[::]:{}", args.source_port),
};
View on GitHub (pinned to 9f96daa2c2)