{"record":{"id":"ffb504359066b66b","repo":"cloudflare/quiche","slug":"connect-to-is-expected-to-be-a-string-containing-ffb504","errorCode":null,"errorMessage":"--connect-to is expected to be a string containing an IPv4 or IPv6 address with a port. E.g. 192.0.2.0:443","messagePattern":"--connect-to is expected to be a string containing an IPv4 or IPv6 address with a port\\. E\\.g\\. 192\\.0\\.2\\.0:443","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"h3i/src/client/mod.rs","lineNumber":574,"sourceCode":"    let connect_url = if !args.omit_sni {\n        args.host_port.split(':').next()\n    } else {\n        None\n    };\n\n    let (peer_addr, bind_addr) = resolve_socket_addrs(args);\n\n    ParsedArgs {\n        peer_addr,\n        bind_addr,\n        connect_url,\n    }\n}\n\nfn resolve_socket_addrs(args: &Config) -> (SocketAddr, SocketAddr) {\n    // Resolve server address.\n    let peer_addr = if let Some(addr) = &args.connect_to {\n        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\")\n    } else {\n        let x = format!(\"https://{}\", args.host_port);\n        *url::Url::parse(&x)\n            .unwrap()\n            .socket_addrs(|| None)\n            .unwrap()\n            .first()\n            .unwrap()\n    };\n\n    // Bind to INADDR_ANY or IN6ADDR_ANY depending on the IP family of the\n    // server address. This is needed on macOS and BSD variants that don't\n    // support binding to IN6ADDR_ANY for both v4 and v6.\n    let bind_addr = match peer_addr {\n        std::net::SocketAddr::V4(_) => format!(\"0.0.0.0:{}\", args.source_port),\n        std::net::SocketAddr::V6(_) => format!(\"[::]:{}\", args.source_port),\n    };\n","sourceCodeStart":556,"sourceCodeEnd":592,"githubUrl":"https://github.com/cloudflare/quiche/blob/9f96daa2c22a4468b0036fb0a0a3894eee6498b8/h3i/src/client/mod.rs#L556-L592","documentation":"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.","triggerScenarios":"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).","commonSituations":"Copying a hostname into --connect-to when doing SNI/host overriding; forgetting the port; IPv6 literals without brackets are handled, but URLs are not.","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."],"exampleFix":"// before\nh3i --host_port example.com:443 --connect-to example.com:443\n// after\nh3i --host_port example.com:443 --connect-to 93.184.216.34:443","handlingStrategy":"validation","validationCode":"use std::net::SocketAddr;\nlet addr: SocketAddr = connect_to.parse()\n    .map_err(|_| \"--connect-to must be IP:port, e.g. 192.0.2.0:443\")?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["cli","socket-address","parsing","panic"],"backgroundTag":"invalid-cli-argument","analyzedSha":"9f96daa2c22a4468b0036fb0a0a3894eee6498b8","analyzedAt":"2026-09-08T11:27:09.536Z","contentChangedAt":"2026-09-08T11:27:09.536Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}