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

  1. Raise resource limits: `ulimit -n 65535` and check `ulimit -u`; raise cgroup `pids.max`.
  2. Check container seccomp/AppArmor profiles allow epoll_create1, eventfd2, and clone/fork; relax or use a supported runtime.
  3. Reduce tokio worker threads via `--worker-threads`/TOKIO_WORKER_THREADS or a custom builder if thread creation is the failure.
  4. Verify kernel version supports epoll/timerfd (Linux >= 2.6.25) or run on a standard host.
  5. 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

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


AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09). Data as JSON: /api/errors/11d8918a246f98ad. Report an issue: GitHub.