shadowsocks/shadowsocks-rust · error
`server`, `server_port`, `method`, `password` must be provid
Error message
`server`, `server_port`, `method`, `password` must be provided together
What it means
This error is thrown when parsing a per-server entry in a shadowsocks-service config (the `servers` array, typically from a JSON config or URL) where the `server`, `server_port`, `method`, and `password` fields are only partially specified. The library requires these four fields to be either all present or all absent (with a special allowance for manager configs supplying none, which defaults the method). A partial combination is structurally ambiguous, so the parser rejects it with ErrorKind::Malformed.
Source
Thrown at crates/shadowsocks-service/src/config.rs:2230
},
},
};
nsvr.set_plugin(plugin);
}
}
if let Some(timeout) = config.timeout.map(Duration::from_secs) {
nsvr.set_timeout(timeout);
}
nconfig.server.push(ServerInstanceConfig::with_server_config(nsvr));
}
(None, None, None, Some(_)) if config_type.is_manager() => {
// Set the default method for manager
}
(None, None, None, None) => (),
_ => {
let err = Error::new(
ErrorKind::Malformed,
"`server`, `server_port`, `method`, `password` must be provided together",
None,
);
return Err(err);
}
}
// Ext servers
if let Some(servers) = config.servers {
for svr in servers {
// Skip if server is disabled
if svr.disabled.unwrap_or(false) {
continue;
}
let address = svr.server;
let port = svr.server_port;View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Add the missing fields so all of `server`, `server_port`, `method`, `password` are present in the server entry
- Or remove all four fields if you intended an empty/default server entry (manager configs only)
- Validate the JSON against the shadowsocks-service config schema before loading
- Use `sslocal`/`ssserver` with a known-good example config as a base
Example fix
// before
{"servers": [{"server": "1.2.3.4", "server_port": 8388}]}
// after
{"servers": [{"server": "1.2.3.4", "server_port": 8388, "method": "aes-256-gcm", "password": "secret"}]} Defensive patterns
Strategy: validation
Validate before calling
let required = ["server", "server_port", "method", "password"];
let present: Vec<_> = required.iter().filter(|k| svr.get(k).map_or(false, |v| !v.is_null())).collect();
if !present.is_empty() && present.len() != required.len() {
panic!("server entry must have all or none of {:?}, missing: {:?}", required, required.iter().filter(|k| !present.contains(k)).collect::<Vec<_>>());
} Type guard
fn is_complete_server_entry(svr: &serde_json::Value) -> bool {
["server", "server_port", "method", "password"].iter().all(|k| svr.get(k).map_or(false, |v| !v.is_null()))
} Try / catch
match Config::load_from_file(path, ConfigType::Server) {
Ok(c) => start(c),
Err(e) => eprintln!("config rejected: {e}; check server entries have all of server/server_port/method/password"),
} Prevention
- Never hand-edit server entries piecemeal; edit all four fields together
- Lint configs with a JSON schema before loading
- Keep password/method in environment-templated variables with non-empty defaults
When it happens
Trigger: Calling Config::load_from_str / load_from_file (or from_url for ss:// URLs) with a server object that has some but not all of `server`, `server_port`, `method`, `password` set — e.g. `server` and `server_port` present but `method` missing, or only `password` present.
Common situations: Hand-edited JSON configs where a field was accidentally deleted or commented out; template-generated configs where variable substitution left a field empty; migrating configs between schema versions where field names changed; copy-pasting a partial server block.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- `protocol` invalid
- invalid `mode`
- missing `locals` for client configuration
- balancer.max_server_rtt must be > 0
- server method doesn't support Extended Identity Header (EIH)
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/63f4027db149519d.
Report an issue: GitHub.