quickwit-oss/quickwit · error

provided arguments should be valid

Error message

provided arguments should be valid

What it means

This panic occurs in `make_channel` when constructing a tonic gRPC `Endpoint` from a `http::Uri` built from the target socket address. It asserts that the URI `http://<socket_addr>/` is well-formed; failure means the authority (the `SocketAddr` string) could not be parsed as a valid URI authority. Because a `SocketAddr` is always `ip:port` and always yields a valid authority, this is effectively an internal invariant assertion guarding against non-IP/invalid addresses reaching this code path.

Source

Thrown at quickwit/quickwit-transport/src/channel.rs:98

                expected_server_name,
            },
        })
    }

    /// Creates a lazily-connected channel to `socket_addr`. The channel reconnects through this
    /// factory's transport, so a reloaded certificate takes effect on the next (re)connection
    /// without rebuilding the channel.
    ///
    /// The function is `async` because `connect_lazy` requires a Tokio runtime context.
    pub async fn make_channel(&self, socket_addr: SocketAddr) -> Channel {
        // The scheme is always `http`: when TLS is enabled our custom connector hands tonic an
        // already-encrypted stream, so tonic must not attempt its own TLS.
        let uri = Uri::builder()
            .scheme("http")
            .authority(socket_addr.to_string())
            .path_and_query("/")
            .build()
            .expect("provided arguments should be valid");

        let mut endpoint = Endpoint::from(uri).connect_timeout(CONNECT_TIMEOUT);

        if let Some(keep_alive) = &self.keep_alive_opt {
            endpoint = endpoint
                .keep_alive_while_idle(true)
                .http2_keep_alive_interval(*keep_alive.interval)
                .keep_alive_timeout(*keep_alive.timeout);
        }
        match &self.mode {
            TransportMode::Plaintext => endpoint.connect_lazy(),
            TransportMode::Tls {
                client_config,
                expected_server_name,
            } => {
                let tls_connector = TlsConnector::from(client_config.clone());
                let server_name = match expected_server_name {
                    Some(server_name) => server_name.clone(),

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Verify the gRPC address configured for the node is a valid `ip:port` (wrap IPv6 literals in brackets when written in configs, though `SocketAddr` handles this)
  2. Check upstream parsing of the address into `SocketAddr` — a failed parse should error earlier, so a panic here usually means a fork/patch bypassed parsing
  3. Rebuild from unmodified sources; on stock Quickwit a valid `SocketAddr` never triggers this
  4. If reproducing on unmodified code, file a bug with the address string

Example fix

// before (passing a hostname string through a SocketAddr-typed path)
let uri = Uri::builder().scheme("http").authority("node.local").build().expect("provided arguments should be valid");
// after
let socket_addr: SocketAddr = "node.local:7281".parse().expect("invalid gRPC address");
let uri = Uri::builder().scheme("http").authority(socket_addr.to_string()).build().expect("provided arguments should be valid");
Defensive patterns

Strategy: validation

Validate before calling

fn validate_grpc_addr(addr: SocketAddr) -> Option<Uri> {
    Uri::builder()
        .scheme("http")
        .authority(addr.to_string())
        .path_and_query("/")
        .build()
        .ok()
}

Type guard

fn is_valid_authority(s: &str) -> bool {
    http::Uri::builder().scheme("http").authority(s).path_and_query("/").build().is_ok()
}

Try / catch

// make_channel panics rather than returning Result; guard upstream by parsing to SocketAddr first
let socket_addr: SocketAddr = addr_str.parse().map_err(|e| anyhow!("invalid gRPC address '{}': {}", addr_str, e))?;

Prevention

When it happens

Trigger: Calling `make_channel` (via `try_new_node` or `cluster_grpc_client`) with a target whose `SocketAddr` string cannot form a valid URI — practically only possible with a malformed custom `EndpointFactory` configuration or if code upstream passes a hostname/string-derived address that fails `Uri::builder(...).build()` instead of a real `SocketAddr`.

Common situations: Misconfigured node gRPC address (e.g. an IPv6 address rendered without brackets, or a string address incorrectly parsed upstream); custom code paths in a fork passing a URI-incompatible authority.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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