Chromium/Puppeteer fails to launch - possible sandbox restriction
kritsakornyodying-tech
HOBBYOP

a month ago

Hi Railway team,

I'm running a Node.js service (Puppeteer + system Chromium via apt) that consistently fails to launch the browser process. I've ruled out the common causes and would appreciate help identifying whether this is a platform-level sandboxing restriction.

Service: line-quotation-bot (production)

Symptom: puppeteer.launch() fails every time with "Failed to launch the browser process!" The stderr only shows benign/expected container noise (dbus socket unavailable, crashpad cpufreq file missing) which are known non-fatal warnings in containerized Chromium.

What I've already ruled out with hard evidence:

  1. Memory — confirmed hundreds of GB free, Node process using ~115MB
  2. Process/thread limits — checked cgroup pids.max (1000) vs pids.current (11-18), nowhere near the limit
  3. Corrupted/missing Chromium binary — chromium --version runs successfully and returns a valid version string
  4. DevTools WebSocket/port issue — switched Puppeteer to pipe: true (stdio-based transport instead of a local TCP port), and the browser process now launches AND Puppeteer successfully connects to it

What actually happens: Immediately after Puppeteer connects via pipe and sends its first CDP command (Target.setDiscoverTargets), the connection closes and Puppeteer reports Protocol error (Target.setDiscoverTargets): Target closed. When I run Chromium directly (bypassing Puppeteer entirely) with --headless=new --no-sandbox --disable-gpu --dump-dom about:blank, the process crashes immediately with signal SIGTRAP (not SIGSEGV/SIGABRT — no clean exit code).

This pattern (process starts, immediately traps/crashes on actual headless rendering) looks consistent with a seccomp/sandbox restriction blocking a syscall Chromium needs even with --no-sandbox passed (which only disables Chrome's own internal sandbox, not the host/container-level restrictions).

My question: Does Railway's container runtime apply syscall-level restrictions (e.g., via seccomp or gVisor) that would block Chromium's headless rendering process from starting, even with --no-sandbox? If so, is there a way to relax this for a specific service, or is running headless Chromium directly inside a Railway service simply not supported? I want to confirm before I migrate to an external headless-browser service.

Dockerfile base image: node:20-slim, Chromium installed via apt-get install chromium (currently version 150.x).

Thanks for any insight!

$10 Bounty

2 Replies

Railway
BOT

a month ago

This thread has been opened as a bounty so the community can help solve it.

Status changed to Open Railway about 1 month ago


dvjn-technosol
FREE

a month ago

Your diagnosis lines up with a known pattern: SIGTRAP immediately on the first real rendering syscall (not SIGSEGV/SIGABRT), with --no-sandbox making no difference, is the classic signature of a host/runtime-level seccomp restriction — not Chrome's own sandbox. --no-sandbox only disables Chrome's internally-configured sandbox (namespaces + its own seccomp-bpf filter); it can't do anything about syscall filtering imposed by the container runtime itself.

This exact symptom is widely documented on other gVisor-backed platforms (Google Cloud Run is the most-reported case) — Chromium's zygote/renderer processes probe for syscalls that gVisor either doesn't implement or emulates incompletely, and the process traps instead of falling back gracefully.

A few things worth trying to further isolate it before concluding it's unfixable:

  • --disable-dev-shm-usage — rules out the classic /dev/shm 64MB-default issue (different failure mode than yours, but cheap to rule out)
  • --single-process — if it survives past the crash point, it's likely process/thread-creation syscalls being blocked, not rendering itself
  • Try an older Chromium build via apt pin (150.x is very new) — if an older build works, it narrows this to a specific syscall Chromium recently started using

That said, whether Railway's runtime applies gVisor/seccomp restrictions isn't something the community can authoritatively confirm — only Railway can. If it turns out to be platform-level sandboxing, an external headless-browser service (Browserless, ScrapingBee, Steel.dev) is the standard workaround people land on for this exact class of issue on similar platforms.


dawinz
FREE

a month ago

Since Chromium itself is crashing with SIGTRAP outside of Puppeteer, I'd try ruling out the package before assuming it's a Railway restriction.

If you're using the Debian chromium package (150.x), try switching to Chrome for Testing or Puppeteer's bundled Chromium instead. I've seen distro-packaged Chromium behave differently in containers.

Also try adding:

args: [

'--headless=new',

'--no-sandbox',

'--disable-setuid-sandbox',

'--disable-dev-shm-usage',

'--single-process',

'--no-zygote',

]

If it still exits with SIGTRAP when running chromium --headless directly, then you've ruled Puppeteer out completely and narrowed it down to Chromium itself or the runtime environment. That makes the next debugging step much clearer.


Welcome!

Sign in to your Railway account to join the conversation.

Loading...