ReFirmLabs/binwalk · critical

No available worker threads!

Error message

No available worker threads!

What it means

A startup sanity check panic: the code queried the number of available worker threads (e.g. via std::thread::available_parallelism) and got a value below 1. Since a thread pool with zero workers can never process files, main() panics immediately rather than proceeding.

Source

Thrown at src/main.rs:127

        Ok(bw) => bw,
    };

    // If the user specified --threads, honor that request; else, auto-detect available parallelism
    let available_workers = cliargs.threads.unwrap_or_else(|| {
        // Get CPU core info
        match thread::available_parallelism() {
            // In case of error use the default
            Err(e) => {
                error!("Failed to retrieve CPU core info: {e}");
                DEFAULT_WORKER_COUNT
            }
            Ok(coreinfo) => coreinfo.get(),
        }
    });

    // Sanity check the number of available worker threads
    if available_workers < 1 {
        panic!("No available worker threads!");
    }

    // Initialize thread pool
    debug!("Initializing thread pool with {available_workers} workers");
    let workers = ThreadPool::new(available_workers);
    let (worker_tx, worker_rx) = mpsc::channel();

    /*
     * Set a custom panic handler.
     * This ensures that when any thread panics, the default panic handler will be invoked
     * _and_ the entire process will exit with an error code.
     */
    let default_panic_handler = panic::take_hook();
    panic::set_hook(Box::new(move |panic_info| {
        default_panic_handler(panic_info);
        process::exit(-1);
    }));

View on GitHub (pinned to 26713972e3)

Solutions

  1. Inspect the runtime environment: run `nproc` / check cgroup cpu.max and cpuset to confirm at least one CPU is visible
  2. Adjust container/sandbox CPU limits so at least 1 CPU is available
  3. Fall back to a minimum of 1 worker thread instead of panicking
  4. Optionally allow a --workers CLI flag to override auto-detection

Example fix

// before
if available_workers < 1 {
    panic!("No available worker threads!");
}
// after
let available_workers = available_workers.max(1);
debug!("Using {available_workers} workers");
Defensive patterns

Strategy: validation

Validate before calling

let workers = std::thread::available_parallelism()
    .map(|n| n.get())
    .unwrap_or(1)
    .max(1);

Type guard

fn sane_worker_count(n: usize) -> usize { if n < 1 { 1 } else { n } }

Prevention

When it happens

Trigger: available_parallelism() returning Ok(0) or a default path yielding 0 — e.g. running under a cgroup/container with an empty or restricted CPU affinity mask, or a sandboxing layer reporting no usable CPUs.

Common situations: Containers/Docker with cpuset quotas pinned to zero CPUs; CI runners with restricted sched_getaffinity; unusual sandboxes (gVisor, some HPC schedulers) that report 0 processors.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of ReFirmLabs/binwalk@26713972e3 (2026-09-06). Data as JSON: /api/errors/d7b3a368377715a0. Report an issue: GitHub.