risingwavelabs/risingwave · error

Failed to parse TOKIO_WORKER_THREADS

Error message

Failed to parse TOKIO_WORKER_THREADS

What it means

In release builds, `main_okk` reads `TOKIO_WORKER_THREADS` to size the tokio runtime. A value that fails `usize` parsing (or is a non-Unicode env var) aborts with `expect`/`panic!` 'Failed to parse TOKIO_WORKER_THREADS', refusing to start with an invalid runtime configuration.

Source

Thrown at src/utils/runtime/src/lib.rs:95

        .install_default()
        .inspect_err(|e| {
            tracing::error!(?e, "Failed to install default crypto provider.");
        })
        .unwrap();
    risingwave_variables::init_server_start_time();

    // `TOKIO` will be read by tokio. Duplicate `RW` for compatibility.
    if let Some(worker_threads) = std::env::var_os("RW_WORKER_THREADS") {
        // safety: single-threaded now.
        unsafe { std::env::set_var("TOKIO_WORKER_THREADS", worker_threads) };
    }

    // Set the default number of worker threads to be at least `MIN_WORKER_THREADS`, in production.
    if !cfg!(debug_assertions) {
        let worker_threads = match std::env::var("TOKIO_WORKER_THREADS") {
            Ok(v) => v
                .parse::<usize>()
                .expect("Failed to parse TOKIO_WORKER_THREADS"),
            Err(std::env::VarError::NotPresent) => std::thread::available_parallelism()
                .expect("Failed to get available parallelism")
                .get(),
            Err(_) => panic!("Failed to parse TOKIO_WORKER_THREADS"),
        };
        if worker_threads < MIN_WORKER_THREADS {
            tracing::warn!(
                "the default number of worker threads ({worker_threads}) is too small, which may lead to issues, increasing to {MIN_WORKER_THREADS}"
            );
            // safety: single-threaded now.
            unsafe { std::env::set_var("TOKIO_WORKER_THREADS", MIN_WORKER_THREADS.to_string()) };
        }
    }

    if let Ok(enable_deadlock_detection) = std::env::var("RW_DEADLOCK_DETECTION") {
        let enable_deadlock_detection = enable_deadlock_detection
            .parse()
            .expect("Failed to parse RW_DEADLOCK_DETECTION");

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Set `TOKIO_WORKER_THREADS` to a plain positive integer (e.g. `8`).
  2. Unset the variable to fall back to available parallelism (subject to MIN_WORKER_THREADS).
  3. Fix deployment manifests/scripts to avoid quoting/whitespace around the value.
  4. Avoid non-numeric placeholders like 'auto' — this code path only accepts usize.

Example fix

// before
TOKIO_WORKER_THREADS=auto ./risingwave compute
// after
TOKIO_WORKER_THREADS=8 ./risingwave compute
Defensive patterns

Strategy: validation

Validate before calling

if let Ok(v) = std::env::var("TOKIO_WORKER_THREADS") {
    assert!(v.trim().parse::<usize>().is_ok(), "TOKIO_WORKER_THREADS must be a positive integer");
}

Try / catch

match std::env::var("TOKIO_WORKER_THREADS") {
    Ok(v) if v.parse::<usize>().is_err() => eprintln!("invalid TOKIO_WORKER_THREADS={v:?}; unset or use an integer"),
    _ => {}
}

Prevention

When it happens

Trigger: Exporting `TOKIO_WORKER_THREADS=abc`, `8.0`, `""`, or a value with whitespace/unicode issues before launching compute/meta/frontend/compactor/ctl in release mode.

Common situations: Kubernetes YAML quoting mistakes ('8 ' vs '8'), copying values with trailing spaces, scripts interpolating empty strings, or setting the value to 'auto' which tokio's own env var accepts elsewhere but this code parses strictly.

Understand the failure class

Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/9554c6dbca6ddef7. Report an issue: GitHub.