shadowsocks/shadowsocks-rust · critical
create tokio Runtime
Error message
create tokio Runtime
What it means
shadowsocks-rust's `create` builds a tokio multi-thread (or current-thread) Runtime via `builder.enable_all().build().expect("create tokio Runtime")`. The expect panics when tokio cannot construct the runtime, which almost always means the requested worker/thread configuration is invalid or runtime resources (threads) cannot be allocated. This happens before any server work starts, so the process aborts immediately during startup.
Source
Thrown at src/service/local.rs:996
})?;
}
info!("shadowsocks local {} build {}", crate::VERSION, crate::BUILD_TIME);
let mut builder = match service_config.runtime.mode {
RuntimeMode::SingleThread => Builder::new_current_thread(),
#[cfg(feature = "multi-threaded")]
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(),
};View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Fix the `--worker-threads` (or equivalent builder config) value — must be >= 1
- Remove explicit runtime tuning flags so tokio defaults are used
- Check container/cgroup thread and pid limits (ulimit -u, pids.max) and raise them
- Upgrade shadowsocks-rust / tokio if running on an unusual platform
Example fix
// before shadowsocks-service --worker-threads 0 ... // after shadowsocks-service --worker-threads 4 ...
Defensive patterns
Strategy: validation
Validate before calling
// before launch
let workers: usize = std::env::args().collect::<Vec<_>>().join(" ")
.split("--worker-threads")
.nth(1).and_then(|s| s.trim().split_whitespace().next())
.and_then(|v| v.parse().ok()).unwrap_or(num_cpus::get());
assert!(workers >= 1, "--worker-threads must be >= 1"); Type guard
fn valid_workers(n: u64) -> bool { n >= 1 } Try / catch
// panic from .expect is not catchable in a meaningful way; validate before launch
match std::panic::catch_unwind(start_service) {
Ok(_) => {},
Err(_) => eprintln!("runtime init failed; check --worker-threads and thread limits"),
} Prevention
- Never pass --worker-threads 0
- Check ulimit -u and cgroup pids.max in containers
- Rely on tokio defaults unless profiling shows a need to tune
When it happens
Trigger: Calling `create` (invoked from `main`) with a `--worker-threads` value of 0, or with thread/stack configuration values tokio's Builder rejects; tokio's `Builder::build()` returning Err (e.g. io error spawning threads).
Common situations: Users passing `--worker-threads 0` on the command line; containers with extremely low thread limits (ulimit / cgroup pids restriction); exotic platforms where tokio cannot spawn threads.
Related errors
- create tokio Runtime
- create tokio Runtime
- create local
- signal
- all plugins are exited. all connections may fail, check your
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/63f2fac8e3aa23c8.
Report an issue: GitHub.