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
- 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)
- 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
- Rebuild from unmodified sources; on stock Quickwit a valid `SocketAddr` never triggers this
- 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
- Always parse configured addresses into SocketAddr (which validates ip:port) before calling channel construction
- Write IPv6 addresses in configs correctly (SocketAddr output includes brackets automatically)
- Keep the endpoint construction unmodified in forks; the constant URI is only valid for ip:port authorities
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
- position of a Kafka partition should never be EOF
- position of a Kinesis shard should never be EOF
- `index_uid` should be a required field
- tasks running the gRPC server should not panic or be cancell
- node not found in pending
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/477d55efd70faac8.
Report an issue: GitHub.