{"record":{"id":"90d398cffa5c8961","repo":"shadowsocks/shadowsocks-rust","slug":"local-port-cannot-be-0","errorCode":null,"errorMessage":"`local_port` cannot be 0","messagePattern":"`local_port` cannot be 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/config.rs","lineNumber":1876,"sourceCode":"                            None => ProtocolType::Socks,\n                            Some(p) => match p.parse::<ProtocolType>() {\n                                Ok(p) => p,\n                                Err(..) => {\n                                    let err = Error::new(\n                                        ErrorKind::Malformed,\n                                        \"`protocol` invalid\",\n                                        Some(format!(\"unrecognized protocol {p}\")),\n                                    );\n                                    return Err(err);\n                                }\n                            },\n                        };\n\n                        let mut local_config = LocalConfig::new(protocol);\n\n                        if let Some(local_port) = local.local_port {\n                            if local_port == 0 {\n                                let err = Error::new(ErrorKind::Malformed, \"`local_port` cannot be 0\", None);\n                                return Err(err);\n                            }\n\n                            let local_addr =\n                                get_local_address(local.local_address, local_port, config.ipv6_first.unwrap_or(false));\n                            local_config.addr = Some(local_addr);\n                        } else if local.local_address.is_some() {\n                            let err = Error::new(ErrorKind::Malformed, \"missing `local_port`\", None);\n                            return Err(err);\n                        }\n\n                        if let Some(local_udp_port) = local.local_udp_port {\n                            if local_udp_port == 0 {\n                                let err = Error::new(ErrorKind::Malformed, \"`local_udp_port` cannot be 0\", None);\n                                return Err(err);\n                            }\n\n                            let local_udp_addr = get_local_address(","sourceCodeStart":1858,"sourceCodeEnd":1894,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/config.rs#L1858-L1894","documentation":"Raised when a local server config entry specifies `local_port` with the value 0. Port 0 is not a valid fixed listen port for the local forwarder (it would normally mean 'OS-assigned', which the config loader explicitly rejects), so it is treated as a malformed config.","triggerScenarios":"A config entry (global `local_port` or a per-`local` entry) contains `\"local_port\": 0`, e.g. as a placeholder that was never filled in.","commonSituations":"Template configs left with 0 as placeholder; programmatically generated configs where a port lookup failed and defaulted to 0; user misunderstanding that 0 means 'auto-assign'.","solutions":["Set `local_port` to a concrete port in the valid range (1-65535), e.g. 1080 for SOCKS.","Remove the `local_port` key if the server should not bind a TCP local port (note: `local_address` without `local_port` triggers a different error).","Fix the upstream code/script that generated the placeholder 0."],"exampleFix":"// before\n{ \"protocol\": \"socks\", \"local_port\": 0 }\n// after\n{ \"protocol\": \"socks\", \"local_port\": 1080 }","handlingStrategy":"validation","validationCode":"fn validate_local_port(cfg: &serde_json::Value) -> Result<(), String> {\n    if let Some(p) = cfg.get(\"local_port\") {\n        let port = p.as_u64().ok_or(\"local_port must be an integer\")?;\n        if port == 0 || port > 65535 {\n            return Err(format!(\"local_port {port} out of range 1-65535\"));\n        }\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match LocalConfig::load_from(config_path) {\n    Ok(cfg) => start(cfg),\n    Err(e) if e.to_string().contains(\"local_port\") => {\n        eprintln!(\"Fix local_port in config: {e}\");\n        std::process::exit(1);\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Never use 0 as a placeholder port; omit the field instead.","Range-check all ports (1-65535) in a config preflight validator.","When generating configs, treat port=0 from the source as an error, not a default.","Check for privileged-port needs only when you pick <1024, not 0."],"tags":["config","port","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-14T16:17:12.679Z"}