shadowsocks/shadowsocks-rust · error
missing `local_port`
Error message
missing `local_port`
What it means
In the final Local-type validation (config.rs), if `local_address` is set but `local_port` is missing or 0, the library returns ErrorKind::MissingField "missing `local_port`". A local server listens on address:port, so a port must accompany the address. The check also asserts port != 0 afterwards.
Source
Thrown at crates/shadowsocks-service/src/config.rs:1802
if let Some(m) = config.mode {
match m.parse::<Mode>() {
Ok(xm) => global_mode = xm,
Err(..) => {
let e = Error::new(
ErrorKind::Malformed,
"malformed `mode`, must be one of `tcp_only`, `udp_only` and `tcp_and_udp`",
None,
);
return Err(e);
}
}
}
match config_type {
ConfigType::Local => {
// Standard config
if config.local_address.is_some() && config.local_port.unwrap_or(0) == 0 {
let err = Error::new(ErrorKind::MissingField, "missing `local_port`", None);
return Err(err);
}
if let Some(local_port) = config.local_port {
// local_port won't be 0, it was checked above
assert_ne!(local_port, 0);
let local_addr =
get_local_address(config.local_address, local_port, config.ipv6_first.unwrap_or(false));
// shadowsocks uses SOCKS5 by default
let mut local_config = LocalConfig::new(ProtocolType::Socks);
local_config.addr = Some(local_addr);
local_config.mode = global_mode;
local_config.protocol = match config.protocol {
None => ProtocolType::Socks,
Some(p) => match p.parse::<ProtocolType>() {
Ok(p) => p,View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Add a non-zero `local_port` to the configuration (e.g. "local_port": 1080).
- In code, set config.local_port = Some(port) before validating.
- If only the address should be configured, also verify the port key is not being overwritten to 0 by template/ENV logic.
Example fix
// before
{ "local_address": "127.0.0.1" }
// after
{ "local_address": "127.0.0.1", "local_port": 1080 } Defensive patterns
Strategy: validation
Validate before calling
if raw.get("local_address").is_some() && raw.get("local_port").and_then(|p| p.as_u64()).unwrap_or(0) == 0 {
return Err("local_address requires a non-zero local_port");
} Type guard
fn local_port_ok(cfg: &Config) -> bool {
cfg.local_address.is_none() || matches!(cfg.local_port, Some(p) if p != 0)
} Try / catch
match Config::load(path) {
Ok(cfg) => start(cfg),
Err(e) if e.to_string().contains("missing `local_port`") => eprintln!("set a non-zero local_port when local_address is specified"),
Err(e) => return Err(e),
} Prevention
- Always set local_port together with local_address in configs.
- Do not use port 0 expecting dynamic assignment; it is rejected.
- Validate generated configs before deployment.
When it happens
Trigger: Calling Config::validate() (or Config::load with ConfigType::Local) where config.local_address is Some but config.local_port is None or Some(0).
Common situations: A JSON config specifying "local_address" but omitting "local_port"; setting local_port to 0 expecting an OS-assigned port (not allowed here); programmatically built configs missing the local_port setter.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- missing `local_dns_addr` or `remote_dns_addr` in configurati
- missing `forward_addr` in configuration
- `local_port` cannot be 0
- `local_udp_port` cannot be 0
- `forward_port` cannot be missing or 0
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/98c748f4e362ed7a.
Report an issue: GitHub.