{"record":{"id":"508f91d664c31f25","repo":"shadowsocks/shadowsocks-rust","slug":"dns-508f91","errorCode":null,"errorMessage":"dns","messagePattern":"dns","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/service/manager.rs","lineNumber":426,"sourceCode":"            && let Some(ref mut m) = config.manager\n        {\n            m.mode = Mode::UdpOnly;\n        }\n\n        if matches.get_flag(\"TCP_AND_UDP\")\n            && let Some(ref mut m) = config.manager\n        {\n            m.mode = Mode::TcpAndUdp;\n        }\n\n        if let Some(acl_file) = matches.get_one::<String>(\"ACL\") {\n            let acl = AccessControl::load_from_file(acl_file)\n                .map_err(|err| ShadowsocksError::LoadAclFailure(format!(\"loading ACL \\\"{acl_file}\\\", {err}\")))?;\n            config.acl = Some(acl);\n        }\n\n        if let Some(dns) = matches.get_one::<String>(\"DNS\") {\n            config.set_dns_formatted(dns).expect(\"dns\");\n        }\n\n        if let Some(dns_cache_size) = matches.get_one::<usize>(\"DNS_CACHE_SIZE\") {\n            config.dns_cache_size = Some(*dns_cache_size);\n        }\n\n        if matches.get_flag(\"IPV6_FIRST\") {\n            config.ipv6_first = true;\n        }\n\n        if let Some(udp_timeout) = matches.get_one::<u64>(\"UDP_TIMEOUT\") {\n            config.udp_timeout = Some(Duration::from_secs(*udp_timeout));\n        }\n\n        if let Some(udp_max_assoc) = matches.get_one::<usize>(\"UDP_MAX_ASSOCIATIONS\") {\n            config.udp_max_associations = Some(*udp_max_assoc);\n        }\n","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/src/service/manager.rs#L408-L444","documentation":"The manager service passes the `--dns` CLI value to `config.set_dns_formatted(dns).expect(\"dns\")`. The panic means the DNS configuration string is malformed. `set_dns_formatted` accepts either a simple DNS server address (e.g. `8.8.8.8` / `[::1]:53`) or a JSON-formatted DNS config object, and rejects anything it cannot parse.","triggerScenarios":"Passing `--dns` with a value that is neither a valid nameserver address (missing port with unparseable format, bad IP) nor valid JSON DNS config (malformed `\"[\\\"8.8.8.8\\\", ...]\"`-style strings, wrong keys).","commonSituations":"Hand-writing JSON DNS configs with quoting mistakes on the shell, using `dns://` URLs or resolv.conf paths which this API doesn't accept, typos in IP addresses.","solutions":["Pass a plain nameserver like `--dns 8.8.8.8` or `--dns \"1.1.1.1:53\"`","If using the JSON form, validate it with `jq` first: ensure it matches shadowsocks Config dns format","Quote the whole JSON value properly for your shell","Move complex DNS config into the config file instead of the CLI flag"],"exampleFix":"// before\n--dns \"dns://8.8.8.8\"\n// after\n--dns \"8.8.8.8:53\"","handlingStrategy":"validation","validationCode":"use std::net::ToSocketAddrs;\nfn valid_dns_value(v: &str) -> bool {\n    v.to_socket_addrs().is_ok() || serde_json::from_str::<serde_json::Value>(v).is_ok()\n}","typeGuard":"null","tryCatchPattern":"// mirror the library call with error reporting\nif let Err(e) = config.set_dns_formatted(dns) {\n    eprintln!(\"invalid --dns value {dns:?}: {e}\");\n    std::process::exit(2);\n}","preventionTips":["Prefer plain nameserver addresses on the CLI","Validate JSON DNS configs with jq before passing them","Do not use dns:// URLs or resolv.conf paths with --dns"],"tags":["cli","dns","parsing","config"],"backgroundTag":"invalid-config-value","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}