shadowsocks/shadowsocks-rust · error
`protocol` invalid
Error message
`protocol` invalid
What it means
This error is raised while parsing a shadowsocks local server configuration when the `protocol` field is present but its string value cannot be parsed into a `ProtocolType` (e.g. it is not one of "socks", "http", "tunnel", etc.). The library fails fast with ErrorKind::Malformed because an unrecognized protocol would otherwise produce a local server that cannot be started. It includes the offending value as detail (`unrecognized protocol {p}`).
Source
Thrown at crates/shadowsocks-service/src/config.rs:1822
}
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,
Err(..) => {
let err = Error::new(
ErrorKind::Malformed,
"`protocol` invalid",
Some(format!("unrecognized protocol {p}")),
);
return Err(err);
}
},
};
#[cfg(target_os = "macos")]
{
local_config
.launchd_tcp_socket_name
.clone_from(&config.launchd_tcp_socket_name);
local_config
.launchd_udp_socket_name
.clone_from(&config.launchd_udp_socket_name);
}
View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Check the config value of `protocol` and use an exact accepted variant, e.g. "socks", "http", "tunnel" (values accepted by ProtocolType::from_str).
- Remove the `protocol` field entirely to get the default (ProtocolType::Socks).
- Verify no trailing whitespace or BOM in the JSON string value.
- Consult the ProtocolType enum docs in the installed shadowsocks-service version, since accepted values can vary by version.
Example fix
// before
{ "protocol": "socks5", "local_port": 1080 }
// after
{ "protocol": "socks", "local_port": 1080 } Defensive patterns
Strategy: validation
Validate before calling
const PROTOCOLS: [&str; 4] = ["socks", "http", "tunnel", "redir"]; // check your version's ProtocolType
fn validate_protocol(cfg: &serde_json::Value) -> Result<(), String> {
match cfg.get("protocol") {
None => Ok(()),
Some(p) => {
let s = p.as_str().ok_or("protocol must be a string")?;
if PROTOCOLS.contains(&s) { Ok(()) } else { Err(format!("unrecognized protocol {s}")) }
}
}
} Type guard
fn is_valid_protocol(s: &str) -> bool {
matches!(s, "socks" | "http" | "tunnel" | "redir")
} Try / catch
match LocalConfig::load_from(config_path) {
Ok(cfg) => start(cfg),
Err(e) if e.kind() == ErrorKind::Malformed => {
eprintln!("Bad config: {e}"); // inspect `protocol` value and fix spelling
std::process::exit(1);
}
Err(e) => return Err(e.into()),
} Prevention
- Keep a JSON schema for your config and validate before loading.
- Only use protocol spellings copied from the official shadowsocks-rust docs.
- Lint configs in CI with a preflight load against the same library version.
- Avoid manual edits on production configs; diff and review changes.
When it happens
Trigger: Loading a local config (JSON/URL) whose per-server or global entry has `protocol` set to a string that does not match any ProtocolType variant — e.g. `"protocol": "socks5"` or `"SOCKS"` or a typo like `"sock"`.
Common situations: Hand-edited config.json files with typos or wrong casing; configs copied from other shadowsocks implementations that use different protocol names; schema drift after upgrading where an old/alias protocol name is no longer accepted.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- invalid `mode`
- `server`, `server_port`, `method`, `password` must be provid
- 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/6027e87ef99d0be2.
Report an issue: GitHub.