{"record":{"id":"2e90afae689ed682","repo":"shadowsocks/shadowsocks-rust","slug":"failed-to-create-serverconfig-error-2e90af","errorCode":null,"errorMessage":"failed to create ServerConfig, error: {}","messagePattern":"failed to create ServerConfig, error: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/service/server.rs","lineNumber":361,"sourceCode":"                    if method.is_none() {\n                        // If method doesn't need a key (none, plain), then we can leave it empty\n                        String::new()\n                    } else {\n                        match crate::password::read_server_password(svr_addr) {\n                            Ok(pwd) => pwd,\n                            Err(..) => panic!(\"`password` is required for server {svr_addr}\"),\n                        }\n                    }\n                }\n            };\n\n            let svr_addr = svr_addr.parse::<ServerAddr>().expect(\"server-addr\");\n            let timeout = matches.get_one::<u64>(\"TIMEOUT\").map(|x| Duration::from_secs(*x));\n\n            let mut sc = match ServerConfig::new(svr_addr, password, method) {\n                Ok(sc) => sc,\n                Err(err) => {\n                    panic!(\"failed to create ServerConfig, error: {}\", err);\n                }\n            };\n            if let Some(timeout) = timeout {\n                sc.set_timeout(timeout);\n            }\n\n            if let Some(p) = matches.get_one::<String>(\"PLUGIN\").cloned() {\n                let plugin = PluginConfig {\n                    plugin: p,\n                    plugin_opts: matches.get_one::<String>(\"PLUGIN_OPT\").cloned(),\n                    plugin_args: Vec::new(),\n                    plugin_mode: matches\n                        .get_one::<String>(\"PLUGIN_MODE\")\n                        .map(|x| {\n                            x.parse::<Mode>()\n                                .expect(\"plugin-mode must be one of `tcp_only` (default), `udp_only` and `tcp_and_udp`\")\n                        })\n                        .unwrap_or(Mode::TcpOnly),","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/src/service/server.rs#L343-L379","documentation":"After parsing the CLI server address, password and method, create() calls shadowsocks-service's ServerConfig::new to validate them; any error it returns (e.g. invalid server address format, method/password combination rejected) is surfaced via this panic. It is a wrapper: the underlying cause is in the `{}` payload.","triggerScenarios":"`--server-addr` fails ServerAddr parsing beyond the earlier expect (bad host/port forms handled by ServerConfig), or ServerConfig::new rejects the (addr, password, method) combination, e.g. a method requiring a key with invalid key material.","commonSituations":"Malformed `-s` values like `8388` (missing host), IPv6 literals without brackets, or password bytes that fail key derivation constraints for the chosen cipher.","solutions":["Read the inner error text after `error:` — it names the exact validation that failed","Use a well-formed server address: host:port, or [ipv6]:port e.g. `-s '[::1]:8388'`","Verify the `--method` and `--password` pair is valid for that cipher (correct key length / encodable password)","Prefer a JSON config file (`-c config.json`) so validation errors come back as structured LoadConfigFailure instead of CLI panics"],"exampleFix":"// before\nssserver -s '8388' -m aes-256-gcm -p secret\n// after\nssserver -s '0.0.0.0:8388' -m aes-256-gcm -p secret","handlingStrategy":"validation","validationCode":"fn looks_like_host_port(s: &str) -> bool {\n    if s.starts_with('[') { s.contains(\"]:\") } else { s.rsplit_once(':').map(|(h,p)| !h.is_empty() && p.parse::<u16>().is_ok()).unwrap_or(false) }\n}\nif !looks_like_host_port(server_addr) { eprintln!(\"bad -s value: {server_addr}\"); std::process::exit(2); }","typeGuard":null,"tryCatchPattern":"// panic is not catchable in stable Rust; inspect the spawned process stderr:\nlet out = Command::new(\"ssserver\").args(&args).output()?;\nif !out.status.success() { eprintln!(\"ssserver failed: {}\", String::from_utf8_lossy(&out.stderr)); }","preventionTips":["Use host:port (or [ipv6]:port) form for -s/--server-addr","Test the full flag set with a dry run or against a JSON config where errors are structured","Keep cipher method and password from the same validated source"],"tags":["cli","configuration","validation"],"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"}