shadowsocks/shadowsocks-rust · critical
create tokio Runtime
Error message
create tokio Runtime
What it means
This panic comes from `.expect("create tokio Runtime")` on `tokio::runtime::Builder::enable_all().build()` in src/service/server.rs:546. The tokio Runtime builder only fails when the underlying OS refuses to create required resources (event loop/epoll/kqueue fds, timer fds, or worker thread setup), meaning the process cannot start its async runtime at all.
Source
Thrown at src/service/server.rs:546
})?;
}
info!("shadowsocks server {} 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, runtime)
};
let main_fut = async move {
let abort_signal = monitor::create_signal_monitor();
let server = run_server(config);
tokio::pin!(abort_signal);
tokio::pin!(server);
match future::select(server, abort_signal).await {
// Server future resolved without an error. This should never happen.
Either::Left((Ok(..), ..)) => Err(ShadowsocksError::ServerExitUnexpectedly(
"server exited unexpectedly".to_owned(),
)),
// Server future resolved with error, which are listener errors in most cases
Either::Left((Err(err), ..)) => Err(ShadowsocksError::ServerAborted(format!("server aborted with {err}"))),View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Raise resource limits: `ulimit -n 65535` and check `ulimit -u`; raise cgroup `pids.max`.
- Check container seccomp/AppArmor profiles allow epoll_create1, eventfd2, and clone/fork; relax or use a supported runtime.
- Reduce tokio worker threads via `--worker-threads`/TOKIO_WORKER_THREADS or a custom builder if thread creation is the failure.
- Verify kernel version supports epoll/timerfd (Linux >= 2.6.25) or run on a standard host.
- Patch the code to map the build error into a ShadowsocksError instead of `.expect` for a clean message.
Example fix
// before
let runtime = builder.enable_all().build().expect("create tokio Runtime");
// after
let runtime = builder
.enable_all()
.build()
.map_err(|e| ShadowsocksError::InternalError(format!("create tokio Runtime: {e}")))?; Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: check fd and thread limits before starting the service
let limits = fs::read_to_string("/proc/self/limits").unwrap_or_default();
assert!(!limits.contains("Max open files 0"), "fd limit too low for tokio runtime"); Try / catch
// If patching: replace expect with error propagation
match builder.enable_all().build() {
Ok(rt) => rt,
Err(e) => {
eprintln!("failed to create tokio runtime: {e}; check ulimit -n, ulimit -u, and container seccomp profile");
std::process::exit(1);
}
} Prevention
- Set generous ulimits (nofile, nproc) in systemd units and container manifests.
- Verify seccomp/AppArmor profiles permit epoll_create1/eventfd2/clone before deploying.
- Set TOKIO_WORKER_THREADS to a modest value in constrained environments.
When it happens
Trigger: Calling `builder.enable_all().build()` when the OS denies creation of the runtime's internal resources: process/thread limits hit (RLIMIT_NPROC, cgroup pids.max), file descriptor exhaustion, missing epoll/eventfd support (very restricted containers, old kernels, seccomp filters blocking syscalls).
Common situations: Running in hardened Docker/Kubernetes pods with seccomp or low pids limits, CI sandboxes, extremely low `ulimit -n`, containers with stripped /proc or missing syscalls (e.g. running under gVisor with restrictive configs).
Related errors
- create tokio Runtime
- create tokio Runtime
- signal
- all plugins are exited. all connections may fail, check your
- open /dev/pf permission denied, consider restart with root u
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/11d8918a246f98ad.
Report an issue: GitHub.