Chromium fails to launch on hosts with unprivileged userns disabled (No usable sandbox) — breaks browse/design/make-pdf
- Dominant language
- TypeScript
- Stars
- 133k
- Forks
- 19.9k
- Avg merge
- 18h 46m
- Merged PRs (30d)
- 26
Description
## Summary
On Linux hosts where unprivileged user namespaces are disabled (default on Ubuntu 23.10+ / 24.04 via AppArmor, and common in containers/CI), the bundled Chromium refuses to launch because gstack starts it **without `--no-sandbox`**. Every skill that drives Chromium fails: `/browse` (screenshot/goto), `/design-consultation` + `/plan-design-review` (mockups), and `/make-pdf`.
gstack version: **1.58.5.0**
## Error
From `make-pdf/dist/pdf setup` (same launch path as browse):
```
[pid=...][err] [FATAL:content/browser/zygote_host/zygote_host_impl_linux.cc:128]
No usable sandbox! If you are running on Ubuntu 23.10+ or another Linux distro
that has disabled unprivileged user namespaces with AppArmor, see
.../apparmor-userns-restrictions.md ... If you want to live dangerously and need
an immediate workaround, you can try using --no-sandbox.
at launch (browse/src/browser-manager.ts:372:35)
at async start (browse/src/server.ts:2974:28)
```
## Environment
- Linux (Ubuntu 23.10+ / kernel with `kernel.apparmor_restrict_unprivileged_userns=1`)
- Playwright Chromium present at `~/.cache/ms-playwright/chromium-*/chrome-linux/chrome` and `chromium_headless_shell-*`
- `chromium` also present but snap-confined (writes to a private `/tmp`, cannot read dotdirs like `~/.gstack`), so it is not a usable fallback either.
## Repro
1. On an Ubuntu 24.04 host (or any host with `sysctl kernel.apparmor_restrict_unprivileged_userns=1`).
2. Run any Chromium-backed skill, e.g. `~/.claude/skills/gstack/make-pdf/dist/pdf setup`, or `browse/dist/browse goto file:///tmp/x.html && browse screenshot /tmp/x.png`.
3. Launch fails with the FATAL sandbox error above; no screenshot/PDF/mockup is produced.
## Root cause
`browser-manager.ts` launches Chromium without `--no-sandbox`, and the host cannot create the sandbox via unprivileged user namespaces.
## Suggested fixes (any one unblocks it)
1. **Detect-and-fallback (preferred):** on Linux, probe whether the sandbox can start; if not, relaunch with `--no-sandbox` and emit a one-line warning. This is what Puppeteer/Playwright wrappers commonly do for CI/containers.
2. **Opt-in env:** honor something like `GSTACK_CHROMIUM_NO_SANDBOX=1` (and/or a general `GSTACK_CHROMIUM_ARGS`) passed through to the launch args. Today neither the browse nor make-pdf binary exposes a no-sandbox flag or arg passthrough.
3. **Docs:** if `--no-sandbox` is undesirable by default, document the host-side fix in setup output: `sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0` (non-persistent) or an AppArmor profile.
## Impact
Hits three skill families on affected hosts (browse, design mockups, make-pdf). Workaround today is to bypass the gstack binaries entirely and drive the Playwright chrome directly with `--no-sandbox` (e.g. `chrome --headless=new --no-sandbox --print-to-pdf`), which loses the gstack styling/daemon.
Contributor guide
Research direction
Start at browse/src/browser-manager.ts:372 and trace the Chromium launch path shared by browse and make-pdf; reproduce with kernel.apparmor_restrict_unprivileged_userns=1. Done means the affected browse, design mockup, and make-pdf flows launch and produce their outputs on such hosts, with the selected fallback or opt-in behavior documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- playwright, typescript
- Domain
- cli, devtools, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100