quickwit-oss/quickwit · error

DNS resolution did not yield any record for hostname

Error message

DNS resolution did not yield any record for hostname {addr:?}

What it means

`get_socket_addr` resolves a host:port to a SocketAddr using Tokio's `lookup_host`. If the address parses but DNS lookup returns an empty iterator — the hostname resolved with no records — it bails with this message. Preceded by a context error for unparseable/failed lookups, this one specifically means resolution succeeded but produced nothing.

Solutions

  1. Verify the hostname exists: `dig <hostname>` / `nslookup <hostname>` from the quickwit node.
  2. Fix the hostname in the config (peer seeds, advertised address, gRPC endpoints).
  3. Add retry/backoff around startup resolution to tolerate DNS propagation delays.
  4. Use IPs directly for static clusters if DNS is unreliable.

Example fix

// before
peer_seeds = ["quickwit-0.internal"]
// after (verify hostname or use address that resolves)
peer_seeds = ["quickwit-0.quickwit-headless.default.svc.cluster.local:7280"]
Defensive patterns

Strategy: retry

Validate before calling

let resolved = tokio::net::lookup_host((host.clone(), port)).await;
if matches!(&resolved, Ok(addrs) if addrs.count() == 0) {
    eprintln!("host {host} resolves to no records; fix DNS before starting");
}

Try / catch

let addr = loop {
    match get_socket_addr(&addr_str).await {
        Ok(a) => break a,
        Err(e) if e.to_string().contains("did not yield any record") => {
            tokio::time::sleep(Duration::from_secs(2)).await; // DNS propagation
        }
        Err(e) => return Err(e),
    }
};

Prevention

When it happens

Trigger: Calling resolve/get_socket_addr with a hostname whose DNS lookup returns zero records: newly created DNS entry not propagated yet, hostname removed, or /etc/hosts entry deleted.

Common situations: Configuring peer addresses in a cluster with a hostname that doesn't exist in DNS; Kubernetes service name typo; DNS zone issues yielding NXDOMAIN-style empty answers; startup racing DNS propagation after container creation.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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

Appendix: source

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

fn is_dormant(interface: &NetworkInterface) -> bool {
    interface.is_dormant()
}

#[cfg(not(any(target_os = "linux", target_os = "android")))]
fn is_dormant(_interface: &NetworkInterface) -> bool {
    false
}

/// Converts an object into a resolved `SocketAddr`.
pub async fn get_socket_addr<T: ToSocketAddrs + std::fmt::Debug>(
    addr: &T,
) -> anyhow::Result<SocketAddr> {
    lookup_host(addr)
        .await
        .with_context(|| format!("failed to parse address or resolve hostname {addr:?}"))?
        .next()
        .ok_or_else(|| {
            anyhow::anyhow!("DNS resolution did not yield any record for hostname {addr:?}")
        })
}

fn is_forwardable_ip(ip_addr: &IpAddr) -> bool {
    static NON_FORWARDABLE_NETWORKS: LazyLock<Vec<IpNetwork>> = LazyLock::new(|| {
        // Blacklist of non-forwardable IP blocks taken from RFC6890
        [
            "0.0.0.0/8",
            "127.0.0.0/8",
            "169.254.0.0/16",
            "192.0.0.0/24",
            "192.0.2.0/24",
            "198.51.100.0/24",
            "2001:10::/28",
            "2001:db8::/32",
            "203.0.113.0/24",
            "240.0.0.0/4",
            "255.255.255.255/32",

View on GitHub (pinned to a39730c5cd)