quickwit-oss/quickwit · error

failed to parse address

Error message

failed to parse address `{}`: hostname is invalid

What it means

`HostAddr::parse_with_default_port` parses `<host>:<port>` strings (with an optional default port when the port is omitted). After extracting the hostname and port, it re-validates the hostname with `is_valid_hostname`; if the hostname part fails validation it rejects the whole address with this error, even though the string may have split cleanly.

Solutions

  1. Correct the hostname portion to valid DNS syntax (alphanumerics and hyphens only) and re-parse.
  2. For IPv6 hosts, wrap the address in brackets: `[::1]:7200` instead of `::1:7200`.
  3. If an IP was intended, verify the IP syntax — a malformed IP falls through to hostname validation and fails there.
  4. Ensure the value is `host` or `host:port` with no extra separators, spaces, or scheme prefix (`http://` must be stripped).

Example fix

// before
let addr: HostAddr = "node_1:7200".parse()?; // invalid hostname
// after
let addr: HostAddr = "node-1:7200".parse()?;
Defensive patterns

Strategy: validation

Validate before calling

fn parse_addr_checked(s: &str, default_port: u16) -> Result<quickwit_common::net::HostAddr, String> {
    let s = s.trim();
    let host_part = s.rsplit_once(':').map(|(h, _)| h).unwrap_or(s);
    if host_part.contains('_') {
        return Err(format!("hostname '{host_part}' contains invalid characters (use hyphens)"));
    }
    s.parse::<quickwit_common::net::HostAddr>().map_err(|e| e.to_string())
}

Try / catch

match addr_str.parse::<quickwit_common::net::HostAddr>() {
    Ok(addr) => use_addr(addr),
    Err(e) if e.to_string().contains("hostname is invalid") => {
        // hint user: check host portion syntax, bracket IPv6
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Parsing an address string whose host portion is not a valid DNS hostname — e.g. `"my_node:7200"` (underscore in host), `"-node:7200"`, an over-long label, or an empty host like `":7200"` — via `HostAddr::from_str` or config fields expecting `host:port`.

Common situations: Malformed `peer_address`/`advertise_address`/gRPC listen addresses in quickwit.yaml, hostnames containing underscores generated by container orchestrators, IPv6 addresses without brackets (`::1:7200` parses the wrong part as hostname), or pasting addresses with hidden whitespace.

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


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/e229b4a0e5856a13. Report an issue: GitHub.

Appendix: source

Thrown at quickwit/quickwit-common/src/net.rs:169

                port: socket_addr.port(),
            });
        }
        if let Ok(ip_addr) = host_addr.parse::<IpAddr>() {
            return Ok(Self {
                host: Host::IpAddr(ip_addr),
                port: default_port,
            });
        }
        let (hostname, port) = if let Some((hostname_str, port_str)) = host_addr.split_once(':') {
            let port_u16 = port_str.parse::<u16>().with_context(|| {
                format!("failed to parse address `{host_addr}`: port is invalid")
            })?;
            (hostname_str, port_u16)
        } else {
            (host_addr, default_port)
        };
        if !is_valid_hostname(hostname) {
            bail!(
                "failed to parse address `{}`: hostname is invalid",
                host_addr
            )
        }
        Ok(Self {
            host: Host::Hostname(hostname.to_string()),
            port,
        })
    }

    /// Resolves the host if necessary and returns a `SocketAddr`.
    pub async fn resolve(&self) -> anyhow::Result<SocketAddr> {
        self.host
            .resolve()
            .await
            .map(|ip_addr| SocketAddr::new(ip_addr, self.port))
    }

View on GitHub (pinned to a39730c5cd)