risingwavelabs/risingwave · critical

Failed to parse RW_DEADLOCK_DETECTION

Error message

Failed to parse RW_DEADLOCK_DETECTION

What it means

`RW_DEADLOCK_DETECTION` is parsed as bool via `.expect("Failed to parse RW_DEADLOCK_DETECTION")` in init_tokio_runtime. Any value that is not `true`/`false` (Rust bool parsing) panics the process at startup. When unset, a debug-assertions-dependent default is applied instead.

Solutions

  1. Set RW_DEADLOCK_DETECTION=true or RW_DEADLOCK_DETECTION=false (exact lowercase spelling) or unset the variable to use the default.
  2. Search deployment manifests for the variable and normalize casing/format.
  3. If you need 1/0 semantics, transform the value in your entrypoint wrapper script instead.

Example fix

// before (unparseable bool)
RW_DEADLOCK_DETECTION=1
// after
RW_DEADLOCK_DETECTION=true
Defensive patterns

Strategy: validation

Validate before calling

match std::env::var("RW_DEADLOCK_DETECTION") {
    Ok(v) if v == "true" || v == "false" => {},
    Err(std::env::VarError::NotPresent) => {},
    other => panic!("RW_DEADLOCK_DETECTION must be 'true' or 'false', got {:?}", other),
}

Prevention

When it happens

Trigger: RW_DEADLOCK_DETECTION set to anything other than exactly "true" or "false" (e.g. "1", "yes", "on", "True", "") while launching any RisingWave binary.

Common situations: Operators copying env conventions from other services where booleans are 1/0 or on/off; YAML/ConfigMap values like "enabled"; locale casing mistakes; accidentally exporting the var empty.

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/b91c5c083500cea2. Report an issue: GitHub.

Appendix: source

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

                .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");
        if enable_deadlock_detection {
            enable_parking_lot_deadlock_detection();
        }
    } else {
        // In case the env variable is not set
        if cfg!(debug_assertions) {
            enable_parking_lot_deadlock_detection();
        }
    }

    if let Ok(profile_path) = std::env::var("RW_PROFILE_PATH") {
        spawn_prof_thread(profile_path);
    }

    let future_with_shutdown = async move {
        let shutdown = CancellationToken::new();
        let mut fut = pin!(f(shutdown.clone()));

View on GitHub (pinned to 6469eb736d)