denoland/deno · critical

Failed to initialize V8 platform (could not start worker thr

Error message

Failed to initialize V8 platform (could not start worker threads). If running in a container, ensure the PID limit is high enough (try --pids-limit=40 or higher).

What it means

Runtime panic from the V8 fatal-error handler installed in cli/lib.rs. When V8 tries to create its platform worker threads and the OS refuses (EAGAIN due to thread/PID limits), V8 reports "Check failed: Start()". Deno detects that message and re-panics with an actionable hint about container PID limits, because V8's raw message is unhelpful.

Source

Thrown at cli/lib.rs:701

      eprintln!(
        "https://panic.deno.com/v{}/{}/{}",
        version,
        env!("TARGET"),
        trace
      );
    }

    orig_hook(panic_info);
    deno_runtime::exit(1);
  }));

  fn error_handler(file: &str, line: i32, message: &str) {
    // Provide a clearer message for thread creation failures, which
    // typically happen when running in containers with low PID limits
    // (e.g. Docker --pids-limit). V8's default error is just
    // "Check failed: Start()" which is unhelpful.
    if message.contains("Check failed: Start()") {
      panic!(
        "Failed to initialize V8 platform (could not start worker threads). \
        If running in a container, ensure the PID limit is high enough \
        (try --pids-limit=40 or higher)."
      );
    }
    // Override C++ abort with a rust panic, so we
    // get our message above and a nice backtrace.
    panic!("Fatal error in {file}:{line}: {message}");
  }

  deno_core::v8::V8::set_fatal_error_handler(error_handler);
}

/// Returns `true` if `panic_info` is a panic from `std`'s print macros caused
/// by the downstream reader of stdout/stderr closing the pipe.
///
/// `println!`/`print!`/`eprintln!`/`eprint!` panic with the literal payload
/// `"failed printing to {stdout,stderr}: <io error>"` when the underlying

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Raise the container PID limit: docker run --pids-limit=40 (or higher) / raise the pids cgroup limit in Kubernetes
  2. Raise the user thread limit: `ulimit -u 4096` (or tune /etc/security/limits.conf)
  3. Reduce concurrent deno processes/parallel test shards, or run with the single-threaded V8 platform (`--single-threaded`) if applicable

Example fix

# before
docker run --pids-limit=10 denoland/deno deno run app.ts
# after
docker run --pids-limit=40 denoland/deno deno run app.ts
Defensive patterns

Strategy: validation

Validate before calling

# preflight inside the container before launching deno
ulimit -u || true
max=$(cat /sys/fs/cgroup/pids.max 2>/dev/null || echo max)
cur=$(cat /sys/fs/cgroup/pids.current 2>/dev/null || echo 0)
[ "$max" = "max" ] || [ "$cur" -lt "$max" ] || { echo 'pid budget exhausted; raise pids limit'; exit 2; }

Prevention

When it happens

Trigger: Starting any deno process (run, repl, test) in a container or namespace where the thread/PID budget is exhausted: Docker `--pids-limit` too low, cgroup pids.max reached, ulimit -u exceeded, or many workers already spawned so V8's platform threads cannot be created.

Common situations: Docker/Kubernetes with default-low pids limits (e.g. --pids-limit=10); CI sandboxes; rootless Podman with narrow user namespaces; parallel test matrices spawning many deno processes on one host.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/6de894d32b15f2ac. Report an issue: GitHub.