{"record":{"id":"e73a3cc9c38f8e9f","repo":"hatoo/oha","slug":"dns-failed-to-load-etc-resolv-conf-err","errorCode":null,"errorMessage":"DNS: failed to load /etc/resolv.conf: {err}","messagePattern":"DNS: failed to load /etc/resolv\\.conf: (.+?)","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"src/main.rs","lineNumber":910,"sourceCode":"    let (res, print_config) = data_collect_future.await;\n\n    printer::print_result(print_config, start, &res, duration)?;\n\n    if let Some(db_url) = opts.db_url {\n        eprintln!(\"Storing results to {db_url}\");\n        db::store(&client, &db_url, start, res.success(), run as i64)?;\n    }\n\n    Ok(())\n}\n\npub(crate) fn system_resolv_conf() -> anyhow::Result<(ResolverConfig, ResolverOpts)> {\n    // Termux (https://github.com/termux/termux-app) is no longer supported:\n    // hickory-resolver 0.26 removed `parse_resolv_conf` on Android, so we can\n    // no longer read `$PREFIX/etc/resolv.conf` via hickory.\n    match hickory_resolver::system_conf::read_system_conf() {\n        Ok(conf) => Ok(conf),\n        Err(err) => fallback_resolver_config(anyhow::anyhow!(\n            \"DNS: failed to load /etc/resolv.conf: {err}\"\n        )),\n    }\n}\n\nfn fallback_resolver_config(err: anyhow::Error) -> anyhow::Result<(ResolverConfig, ResolverOpts)> {\n    // Notify the user that we had to fall back to a default resolver configuration.\n    eprintln!(\"{err}\");\n\n    let config = ResolverConfig::default();\n    let opts = ResolverOpts::default();\n    Ok((config, opts))\n}\n\nenum WorkMode {\n    Debug,\n    FixedNumber {\n        n_requests: usize,","sourceCodeStart":892,"sourceCodeEnd":928,"githubUrl":"https://github.com/hatoo/oha/blob/4efba2d113d165aaaf7533f5d2893e7cc57ebfc1/src/main.rs#L892-L928","documentation":"system_resolv_conf builds the DNS resolver configuration by reading the system's /etc/resolv.conf via hickory-resolver. If read_system_conf fails (file missing, unreadable, or unparseable — note Android/Termux is unsupported since hickory 0.26), the error is wrapped with the 'DNS: failed to load /etc/resolv.conf' prefix and passed to fallback_resolver_config, which may proceed with a fallback resolver or surface the error.","triggerScenarios":"Container images or minimal systems without /etc/resolv.conf; restrictive file permissions on resolv.conf; running on Android/Termux where hickory 0.26+ removed that capability; a malformed resolv.conf that hickory cannot parse.","commonSituations":"Scratch/distroless Docker images lacking resolv.conf; sandboxed CI runners; Android environments after upgrading hickory-resolver.","solutions":["Ensure /etc/resolv.conf exists and is readable (e.g. create one with `nameserver 8.8.8.8` in containers).","Fix file permissions on /etc/resolv.conf.","On Android/Termux, note hickory 0.26 no longer supports it; run on a supported platform or supply a fallback config path.","Inspect the wrapped `{err}` message for the underlying cause."],"exampleFix":"// before\n# scratch container without resolv.conf\noha https://example.com\n// after\nRUN echo 'nameserver 8.8.8.8' > /etc/resolv.conf\noha https://example.com","handlingStrategy":"fallback","validationCode":"use std::path::Path;\nif !Path::new(\"/etc/resolv.conf\").exists() {\n    eprintln!(\"Warning: /etc/resolv.conf missing; DNS resolution may fail\");\n}","typeGuard":null,"tryCatchPattern":"match system_resolv_conf() {\n    Ok((config, opts)) => /* build resolver */,\n    Err(e) if e.to_string().contains(\"failed to load /etc/resolv.conf\") => {\n        // use a hardcoded ResolverConfig with public DNS, e.g. 8.8.8.8\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Ensure base container images include /etc/resolv.conf (echo 'nameserver 8.8.8.8' > /etc/resolv.conf).","Avoid Android/Termux targets with hickory-resolver >= 0.26.","Keep resolv.conf readable and syntactically valid; check the wrapped {err} detail when it fires."],"tags":["dns","resolv-conf","network","resolver"],"backgroundTag":"config-file-not-found","analyzedSha":"4efba2d113d165aaaf7533f5d2893e7cc57ebfc1","analyzedAt":"2026-09-09T16:24:23.306Z","contentChangedAt":"2026-09-09T16:24:23.306Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}