[GH-ISSUE #2959] Linux configuration without a /etc/resolv.conf is not working #1100

Open
opened 2026-03-16 01:36:26 +03:00 by kerem · 2 comments
Owner

Originally created by @stormshield-gt on GitHub (Apr 30, 2025).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2959

Describe the bug
In my current Linux configuration, I don't have a /etc/resolv.conf which makes failed the hickory resolver.

The Linux man page said that if this file does not exist, only the name server on the local machine will be queried, so I think my configuration is valid.

To Reproduce
Steps to reproduce the behavior:

You need to have a machine without /etc/resolv.conf.

# Cargo.toml
[package]
name = "playground"
version = "0.0.0"
edition = "2024"

[dependencies]
reqwest = { version = "0.12.15", features = ["rustls-tls", "hickory-dns"] }
rustls = "0.23.26"
tokio = { version = "1.44.2", features = ["full"] }
// main.rs
#[tokio::main]
async fn main() {
    let body = reqwest::get("https://www.rust-lang.org")
        .await
        .unwrap()
        .text()
        .await
        .unwrap();

    println!("body = {body:?}")
}

I get this error :

thread 'main' panicked at src/main.rs:5:10:
called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Request, url: "https://www.rust-lang.org/", source: hyper_util::client::legacy::Error(Connect, ConnectError("dns error", HickoryDnsSystemConfError(ResolveError { kind: Io(Os { code: 2, kind: NotFound, message: "No such file or directory" }) }))) }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

But if i deactivate hickory DNS, it will work just fine.

#[tokio::main]
async fn main() {
    let body = reqwest::ClientBuilder::new()
        .no_hickory_dns()
        .build()
        .unwrap()
        .get("https://www.rust-lang.org")
        .send()
        .await
        .unwrap()
        .text()
        .await
        .unwrap();

    println!("body = {body:?}")
}

Manually adding a /etc/resolv.conf will solve the problem, but I require tweaking the local DNS configuration, which is not always possible.

sudo sh -c 'echo "nameserver 127.0.0.1" > /etc/resolv.conf'

Expected behavior

I would have expected to work out of the box, even if /etc/resolv.conf doesn't exist.

System:

  • OS: Linux
  • Architecture: x86_64

Version:
Crate: resolver
Version: 0.24.4

Originally created by @stormshield-gt on GitHub (Apr 30, 2025). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2959 **Describe the bug** In my current Linux configuration, I don't have a `/etc/resolv.conf` which makes failed the hickory resolver. The Linux [man page](https://www.man7.org/linux/man-pages/man5/resolver.5.html) said that if this file does not exist, only the name server on the local machine will be queried, so I think my configuration is valid. **To Reproduce** Steps to reproduce the behavior: You need to have a machine without `/etc/resolv.conf`. ```toml # Cargo.toml [package] name = "playground" version = "0.0.0" edition = "2024" [dependencies] reqwest = { version = "0.12.15", features = ["rustls-tls", "hickory-dns"] } rustls = "0.23.26" tokio = { version = "1.44.2", features = ["full"] } ``` ```rust // main.rs #[tokio::main] async fn main() { let body = reqwest::get("https://www.rust-lang.org") .await .unwrap() .text() .await .unwrap(); println!("body = {body:?}") } ``` I get this error : ```sh thread 'main' panicked at src/main.rs:5:10: called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Request, url: "https://www.rust-lang.org/", source: hyper_util::client::legacy::Error(Connect, ConnectError("dns error", HickoryDnsSystemConfError(ResolveError { kind: Io(Os { code: 2, kind: NotFound, message: "No such file or directory" }) }))) } note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` But if i deactivate hickory DNS, it will work just fine. ```rust #[tokio::main] async fn main() { let body = reqwest::ClientBuilder::new() .no_hickory_dns() .build() .unwrap() .get("https://www.rust-lang.org") .send() .await .unwrap() .text() .await .unwrap(); println!("body = {body:?}") } ``` Manually adding a `/etc/resolv.conf` will solve the problem, but I require tweaking the local DNS configuration, which is not always possible. ```sh sudo sh -c 'echo "nameserver 127.0.0.1" > /etc/resolv.conf' ``` **Expected behavior** I would have expected to work out of the box, even if `/etc/resolv.conf` doesn't exist. **System:** - OS: Linux - Architecture: x86_64 **Version:** Crate: resolver Version: 0.24.4
Author
Owner

@djc commented on GitHub (Apr 30, 2025):

Hmm, I feel like from the point of a resolver library written in Rust it is pretty reasonable to refuse to guess the resolver configuration if it fails to find one in the well-known location. While Linux may document in the manual for the resolver configuration file what behavior the system resolver will use when this file is not present, I feel like that behavior might be surprising (as an expectation from Rust library API) especially on other platforms.

Why do you want to enable the Hickory option in reqwest?

Manually adding a /etc/resolv.conf will solve the problem, but I require tweaking the local DNS configuration, which is not always possible.

I'm not completely sure what you mean by this.

<!-- gh-comment-id:2842207542 --> @djc commented on GitHub (Apr 30, 2025): Hmm, I feel like from the point of a resolver library written in Rust it is pretty reasonable to refuse to guess the resolver configuration if it fails to find one in the well-known location. While Linux may document in the manual for the resolver configuration file what behavior the system resolver will use when this file is not present, I feel like that behavior might be surprising (as an expectation from Rust library API) especially on other platforms. Why do you want to enable the Hickory option in reqwest? > Manually adding a /etc/resolv.conf will solve the problem, but I require tweaking the local DNS configuration, which is not always possible. I'm not completely sure what you mean by this.
Author
Owner

@stormshield-gt commented on GitHub (Apr 30, 2025):

Thanks for the quick response! I see your point about how this might be surprising.

Why do you want to enable the Hickory option in reqwest?

It's not a choice of mine; it's the testcontainers library I'm using. I precise that testcontainers let you tweak the request configuration, so I can use no_hickory_dns() to "fix" the problem.

I'm not completely sure what you mean by this.

Editing /etc/resolv.conf requires root privilege, which might not be available to a user in a hardened environment.

<!-- gh-comment-id:2842275723 --> @stormshield-gt commented on GitHub (Apr 30, 2025): Thanks for the quick response! I see your point about how this might be surprising. > Why do you want to enable the Hickory option in reqwest? It's not a choice of mine; it's the [testcontainers](https://github.com/testcontainers/testcontainers-rs/blob/1643442389be01e29d8709dd93287bbdab78db21/testcontainers/Cargo.toml#L32) library I'm using. I precise that `testcontainers` let you tweak the `request` configuration, so I can use `no_hickory_dns()` to "fix" the problem. > I'm not completely sure what you mean by this. Editing `/etc/resolv.conf` requires `root` privilege, which might not be available to a user in a hardened environment.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#1100
No description provided.