shadowsocks/shadowsocks-rust · critical
create local
Error message
create local
What it means
After building the tokio runtime, `create` calls `Server::new(config).await.expect("create local")` to construct the local server instance. The panic means the server could not be created from the supplied configuration — typically invalid listener addresses, failed binding-related setup, or bad config values rejected by `Server::new`. Process exits immediately at startup.
Source
Thrown at src/service/local.rs:1004
RuntimeMode::MultiThread => {
let mut builder = Builder::new_multi_thread();
if let Some(worker_threads) = service_config.runtime.worker_count {
builder.worker_threads(worker_threads);
}
builder
}
};
let runtime = builder.enable_all().build().expect("create tokio Runtime");
(config, service_config, runtime)
};
let main_fut = async move {
let config_path = config.config_path.clone();
let instance = Server::new(config).await.expect("create local");
let reload_task = match config_path {
Some(config_path) => ServerReloader {
config_path: config_path.clone(),
balancer: instance.server_balancer().clone(),
}
.launch_reload_server_task()
.boxed(),
None => future::pending().boxed(),
};
let abort_signal = monitor::create_signal_monitor();
let server = instance.run();
let reload_task = reload_task.fuse();
let abort_signal = abort_signal.fuse();
let server = server.fuse();
View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Validate the server config (addresses, ports, method/password) before starting
- Check the underlying error logged before the panic — fix the offending config field
- Test the config with `sslocal --check-config` if available
- Ensure bind addresses are valid IP:port and not already restricted
Example fix
// before sslocal -b "localhost:notaport" -s ... // after sslocal -b "127.0.0.1:1080" -s ...
Defensive patterns
Strategy: validation
Validate before calling
// validate bind address before starting
let addr: std::net::SocketAddr = args.bind_addr
.parse().expect("bind-addr must be host:port");
assert!(addr.port() > 0, "port must be > 0"); Type guard
fn is_valid_socket_addr(s: &str) -> bool { s.parse::<std::net::SocketAddr>().is_ok() } Try / catch
// run the server future and inspect its error instead of panicking
match Server::new(config).await {
Ok(srv) => srv.serve().await,
Err(e) => eprintln!("failed to create local server: {e}"),
} Prevention
- Run with --check-config / validate configs in CI before deploy
- Use explicit IP:port for -b values
- Keep plugin paths absolute and executable
When it happens
Trigger: `Server::new(config)` returning Err inside `create`, called from `main`: unparseable or unusable server configuration (bad local address, invalid plugin/balancer config, failed ACL/DNS setup).
Common situations: Malformed `-b`/`--bind-addr` values, invalid server address strings in the local forward config, config-file entries that `Server::new` cannot materialize, plugin paths that don't exist.
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
- server config create failed
- missing any valid servers in configuration
- missing manager config
- logging
- method
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/0fb83543a11468a9.
Report an issue: GitHub.