shadowsocks/shadowsocks-rust · error

initialize DNS resolver with system-config failed, error: {}

Error message

initialize DNS resolver with system-config failed, error: {}

What it means

shadowsocks failed to build a DNS resolver from the OS system configuration (e.g. /etc/resolv.conf) when using the hickory-dns (trust-dns) backend. The underlying cause is the wrapped hickory resolver bootstrap error; shadowsocks wraps it into io::ErrorKind::Other and aborts resolver creation, so any lookup using this resolver cannot proceed.

Source

Thrown at crates/shadowsocks/src/dns_resolver/hickory_dns_resolver.rs:195

                    // Only ip_strategy should be changed. Why Ipv4AndIpv6? See comments above.
                    opts.ip_strategy = LookupIpStrategy::Ipv4AndIpv6;

                    // Enable EDNS0 for large records
                    opts.edns0 = true;

                    trace!("initializing DNS resolver with system-config opts {:?}", opts);

                    match builder.build() {
                        Ok(resolver) => Ok(resolver),
                        Err(err) => {
                            error!("initialize DNS resolver with config failed, error: {}", err);
                            Err(io::Error::new(io::ErrorKind::Other, err))
                        }
                    }
                }
                Err(err) => {
                    error!("initialize DNS resolver with system-config failed, error: {}", err);
                    Err(io::Error::new(io::ErrorKind::Other, err))
                }
            }
        }
    }
}

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Check that /etc/resolv.conf exists and is well-formed (valid nameserver lines) in the runtime environment
  2. Inspect the inner error text logged by error! to identify the hickory-dns root cause
  3. Fall back to the built-in (non-hickory) DNS resolver, e.g. use_dns_resolver with the ordinary resolver instead of hickory-dns
  4. Verify the hickory-dns feature/version matches what shadowsocks expects and update both crates together

Example fix

// before
let resolver = hickory_dns_system_resolver().await?;
// after
let resolver = match hickory_dns_system_resolver().await {
    Ok(r) => r,
    Err(e) => {
        log::warn!("hickory system resolver unavailable: {}", e);
        DnsResolver::dns().await // built-in fallback
    }
};
Defensive patterns

Strategy: fallback

Validate before calling

if !std::path::Path::new("/etc/resolv.conf").exists() {
    eprintln!("system DNS config missing; use built-in resolver");
}

Try / catch

let resolver = match hickory_dns_system_resolver().await {
    Ok(r) => r,
    Err(e) => { warn!("hickory resolver failed: {}", e); DnsResolver::dns().await? }
};

Prevention

When it happens

Trigger: Calling create_resolver (via hickory_dns_system_resolver, hickory_dns_notify_update_dns, or hickory_resolver) when the system DNS config is missing, unreadable, or malformed, or when hickory-dns fails to bootstrap its runtime/connection for the configured nameservers.

Common situations: Containers or minimal images without /etc/resolv.conf; malformed resolv.conf entries; hickory-dns version incompatibilities; sandboxed environments where reading system config is blocked; IPv6-only or broken nameserver entries.

Related errors


AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09). Data as JSON: /api/errors/8357fd1f3d7d95a5. Report an issue: GitHub.