From ee6e0f8a24be94aa84ddb314ae11dbf899ac03ee Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Wed, 1 Jul 2026 15:54:52 +0800 Subject: [PATCH 1/2] fix: fall back to default DNS resolver when system config is unparseable litep2p's `with_system_resolver()` reads the OS resolver config via `hickory read_system_conf()` at node startup. When `/etc/resolv.conf` contains a nameserver the parser rejects (e.g. macOS zoned link-local IPv6 `fe80::1%en0`), the read errors and the whole service aborts with `CannotReadSystemDnsConfig`, so the node cannot start at all. Log the parse failure and fall back to the default resolver instead of aborting, keeping #586's "prefer system DNS" intent while no longer bricking startup on hosts with a nameserver hickory can't parse. --- client/litep2p/src/lib.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/client/litep2p/src/lib.rs b/client/litep2p/src/lib.rs index 4ed87ed1..0a39391f 100644 --- a/client/litep2p/src/lib.rs +++ b/client/litep2p/src/lib.rs @@ -155,8 +155,19 @@ impl Litep2p { let mut listen_addresses = vec![]; let (resolver_config, resolver_opts) = if litep2p_config.use_system_dns_config { - hickory_resolver::system_conf::read_system_conf() - .map_err(|e| Error::CannotReadSystemDnsConfig(e.into()))? + // Some hosts advertise nameservers hickory can't parse (e.g. macOS zoned + // link-local IPv6 `fe80::1%en0`); log and fall back instead of aborting startup. + match hickory_resolver::system_conf::read_system_conf() { + Ok(conf) => conf, + Err(error) => { + tracing::error!( + target: LOG_TARGET, + ?error, + "failed to read system DNS config; falling back to default resolver", + ); + (Default::default(), Default::default()) + }, + } } else { (Default::default(), Default::default()) }; From 3e39d41e195e8b46f321f70291712a6c1f62d3ac Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Wed, 1 Jul 2026 16:41:03 +0800 Subject: [PATCH 2/2] defautl to google DNS like previous hickory versions --- client/litep2p/src/lib.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/client/litep2p/src/lib.rs b/client/litep2p/src/lib.rs index 0a39391f..9358c98e 100644 --- a/client/litep2p/src/lib.rs +++ b/client/litep2p/src/lib.rs @@ -50,7 +50,10 @@ use crate::{ #[cfg(feature = "websocket")] use crate::transport::websocket::WebSocketTransport; -use hickory_resolver::TokioResolver; +use hickory_resolver::{ + config::{ResolverConfig, GOOGLE}, + TokioResolver, +}; use multiaddr::{Multiaddr, Protocol}; use transport::Endpoint; use types::ConnectionId; @@ -155,17 +158,18 @@ impl Litep2p { let mut listen_addresses = vec![]; let (resolver_config, resolver_opts) = if litep2p_config.use_system_dns_config { - // Some hosts advertise nameservers hickory can't parse (e.g. macOS zoned - // link-local IPv6 `fe80::1%en0`); log and fall back instead of aborting startup. + // `ResolverConfig::default()` has no nameservers since hickory 0.26, so on a + // failed system read fall back to public DNS rather than leave the node unable + // to resolve `/dns/` peers. match hickory_resolver::system_conf::read_system_conf() { Ok(conf) => conf, Err(error) => { tracing::error!( target: LOG_TARGET, ?error, - "failed to read system DNS config; falling back to default resolver", + "failed to read system DNS config; falling back to public DNS", ); - (Default::default(), Default::default()) + (ResolverConfig::udp_and_tcp(&GOOGLE), Default::default()) }, } } else {