rust-lang/rust · error · io::Error

failed to lookup address information: {detail}

Error message

failed to lookup address information: {detail}

What it means

Emitted by Rust std's HermitOS getaddrinfo wrapper cvt_gai when the underlying Hermit network stack returns a non-zero error code from name resolution. The detail string is hardcoded empty on Hermit (libc::gai_strerror is unavailable), so the message carries no OS-level explanation. ErrorKind is Uncategorized, which is why it surfaces as a generic io::Error.

Source

Thrown at library/std/src/sys/net/connection/socket/hermit.rs:27

use crate::net::{Shutdown, SocketAddr};
use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd};
use crate::sys::fd::FileDesc;
use crate::sys::{AsInner, FromInner, IntoInner};
pub use crate::sys::{cvt, cvt_r};
use crate::time::{Duration, Instant};
use crate::{cmp, mem};

#[expect(non_camel_case_types)]
pub type wrlen_t = usize;

pub fn cvt_gai(err: i32) -> io::Result<()> {
    if err == 0 {
        return Ok(());
    }

    let detail = "";

    Err(io::Error::new(
        io::ErrorKind::Uncategorized,
        &format!("failed to lookup address information: {detail}")[..],
    ))
}

pub fn init() {}

#[derive(Debug)]
pub struct Socket(FileDesc);

impl Socket {
    pub fn new(fam: i32, ty: i32) -> io::Result<Socket> {
        let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?;
        Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) }))
    }

    pub fn new_pair(_fam: i32, _ty: i32) -> io::Result<(Socket, Socket)> {
        unimplemented!()

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Verify the Hermit network driver is loaded and a gateway/DNS server is configured for the VM.
  2. Pass a literal IP address instead of a hostname to bypass the resolver entirely.
  3. Check hostname validity and address-family support in the Hermit network stack before connecting.
  4. Inspect the underlying Hermit network error via its logs, since std gives no detail string.

Example fix

// before
let addrs = ("api.example.com", 443).to_socket_addrs()?;

// after
let addr: SocketAddr = ([93,184,216,34], 443).into();
let s = TcpStream::connect(addr)?;
Defensive patterns

Strategy: validation

Validate before calling

fn resolve_or_ip(host: &str, port: u16) -> io::Result<std::net::SocketAddr> {
    if let Ok(ip) = host.parse::<std::net::IpAddr>() {
        return Ok(std::net::SocketAddr::new(ip, port));
    }
    (host, port).to_socket_addrs()?.next().ok_or_else(||
        io::Error::new(io::ErrorKind::Uncategorized, "no addr"))
}

Try / catch

match (host, port).to_socket_addrs() {
    Ok(mut it) => Ok(it.next().unwrap()),
    Err(e) if e.to_string().contains("failed to lookup address information") => {
        // log Hermit network state, then fallback to configured IP
        Err(e)
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Any DNS lookup (to_socket_addrs, TcpStream::connect with a hostname, UdpSocket::bind) on the Hermit unikernel target when the resolver fails - e.g. unreachable DNS server, malformed hostname, unsupported address family, or network driver not initialized. cvt_gai returns the formatted error for every non-zero gai return.

Common situations: Running a networked Rust program under the HermitOS unikernel without a configured network gateway; DNS server unreachable inside the VM; hostname syntax unsupported by the unikernel resolver.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/a5f524cbce26fca5. Report an issue: GitHub.