shadowsocks/shadowsocks-rust · critical
all plugins are exited. all connections may fail, check your
Error message
all plugins are exited. all connections may fail, check your configuration
What it means
The load-balancer's plugin supervisor task panics when every external plugin process (e.g. v2ray-plugin, simple-obfs) it spawned has exited. Once no plugin process is alive, all proxied connections will fail, so the balancer aborts loudly instead of failing silently. It indicates the plugin binary keeps dying, usually because of a bad plugin configuration or missing binary.
Source
Thrown at crates/shadowsocks-service/src/local/loadbalancing/ping_balancer.rs:297
for plugin in plugins {
vfut.push(async move {
match plugin.join().await {
Ok(status) => {
error!("plugin exited with status: {}", status);
Ok(())
}
Err(err) => {
error!("plugin exited with error: {}", err);
Err(err)
}
}
});
}
let _ = future::join_all(vfut).await;
panic!("all plugins are exited. all connections may fail, check your configuration");
});
Some(plugin_abortable)
}
};
let (best_tcp_idx, best_udp_idx) = PingBalancerBuilder::find_best_idx(&servers, mode);
let balancer_context = Self {
servers,
best_tcp_idx: AtomicUsize::new(best_tcp_idx),
best_udp_idx: AtomicUsize::new(best_udp_idx),
context,
mode,
max_server_rtt,
check_interval,
check_best_interval,
best_task_notify: Notify::new(),View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Fix the plugin binary path and verify it runs standalone with the configured args
- Correct the `--plugin-opts` value against the plugin's documentation
- Check plugin stderr logs in the terminal to see why it exits
- Remove the plugin entry if it is not needed, or pin a working plugin version
Example fix
// before
{"local_address":"127.0.0.1","local_port":1080,"server":"ss.example.com","plugin":"obfs-local","plugin_opts":"obfs=http;obfs-host=wrong-host"}
// after
{"local_address":"127.0.0.1","local_port":1080,"server":"ss.example.com","plugin":"obfs-local","plugin_opts":"obfs=http;obfs-host=real.example.com"} Defensive patterns
Strategy: validation
Validate before calling
// before building the balancer, verify the plugin runs: Command::new(plugin_binary).args(parse_plugin_opts(opts)).status()?.exit_ok()?;
Prevention
- Test the plugin binary standalone with the exact same args before wiring it in
- Keep absolute paths for plugin binaries in config
- Monitor plugin stderr output at startup
- Pin plugin versions and retest after upgrades
When it happens
Trigger: Panic in `LocalBuilder::new` when building a load-balancing local server with plugin instances: all spawned plugin child processes terminated (plugin_abortable futures all finished) before the balancer can route traffic.
Common situations: Wrong plugin binary path in config so the process exits immediately; invalid plugin options passed to the plugin (e.g. bad TLS args); plugin crashes on startup due to missing libraries or incompatible config; server address/port rejected by the plugin.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- unsupported syslog facility: {}
- `password` is required for server {svr_addr}
- failed to create ServerConfig, error: {}
- tunnel requires forward address
- missing local_dns_addr
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/9bf0b26843e577e3.
Report an issue: GitHub.