Repository navigation
[Bug]: Linux headless: orca serve v1.4.229 accepts WebSocket connections but HTTP requests hang indefinitely (possible missing webClientRoot) #30100
Description
Operating system
Linux
Orca version
v1.4.229
Details
[Bug] Linux headless: orca serve v1.4.229 accepts connections but HTTP requests never receive a response
Summary
On a fresh Ubuntu 24.04.5 headless LXC installation, orca serve v1.4.229 starts, initializes runtime pairing, and listens on port 6768, but all HTTP GET requests to the public port time out without any response headers. The expected Web client URL is absent from startup output. In contrast, the internal Electron HTTP server started by Orca serves the web client successfully (HTTP 200).
The public HTTP timeout also occurs on a separate existing Ubuntu headless installation. On that existing host, the same configuration with v1.4.217 returned HTTP 200 for GET /. A macOS installation returned HTTP 200 as well. This suggests a regression affecting at least these headless Linux deployments; it has not been established that all Linux installations are affected.
Environment
- Ubuntu 24.04.5 LTS, amd64, fresh headless LXC, running as root; no desktop session or paired client.
- Official package:
orca-ide_1.4.229_amd64.deb, installed viaapt. dpkg -s orca-ide:Version: 1.4.229.- Startup:
ELECTRON_DISABLE_SANDBOX=1 LIBGL_ALWAYS_SOFTWARE=1 orca-ide serve --port 6768 --pairing-address http://127.0.0.1:6768. - Reported daemon build:
orcad 0.1.0+379585478820(eda94f324614717e), Node 24.21.0 ABI 137. - Electron version from process command line: 43.7.8.
- No
DISPLAYset in the shell or inspected Electron process; an Orca-launchedXvfb :99process was observed.
Reproduction steps
-
On a fresh Ubuntu 24.04 amd64 headless LXC, install the official v1.4.229 DEB. The following dependencies were installed in the reproduction:
apt update apt install -y curl ca-certificates xvfb \ libgtk-3-0t64 libnss3 libatk1.0-0t64 \ libatk-bridge2.0-0t64 libgbm1 libasound2t64 \ libxtst6 libcups2t64 libdrm2 libxkbcommon0 \ libpango-1.0-0 libcairo2 libatspi2.0-0t64 \ libxcomposite1 libxdamage1 libxfixes3 \ libxrandr2 libxrender1 libx11-xcb1 \ libxcb-dri3-0 libxss1 curl -fL -O https://github.com/stablyai/orca/releases/download/v1.4.229/orca-ide_1.4.229_amd64.deb apt install -y ./orca-ide_1.4.229_amd64.deb
-
Start Orca in the foreground (no systemd required):
ELECTRON_DISABLE_SANDBOX=1 LIBGL_ALWAYS_SOFTWARE=1 \ orca-ide serve --port 6768 \ --pairing-address http://127.0.0.1:6768
Representative startup output (pairing secret redacted):
[serve] running on orcad 0.1.0+379585478820 Orca server ready Bound endpoint: ws://0.0.0.0:6768 Advertised endpoint: ws://127.0.0.1:6768 Build: 0.1.0+379585478820 (eda94f324614717e), Node 24.21.0 ABI 137 Terminal daemon: live — PTY self-test passed (pty-spawn: healthy) Pairing URL: orca://pair?code=<REDACTED> [agent-state-rules] download failed: HTTP 404No
Web client URLappears, althoughorca-ide serve --helpdocuments that one is printed when the bundle is available. Theagent-state-rules404 may be unrelated. -
From another shell, request the public endpoint:
curl -v --max-time 10 http://127.0.0.1:6768/
Actual result:
* Connected to 127.0.0.1 (127.0.0.1) port 6768 > GET / HTTP/1.1 > Host: 127.0.0.1:6768 > * Operation timed out after 10002 milliseconds with 0 bytes received curl: (28) Operation timed out after 10002 milliseconds with 0 bytes received -
Repeat with different paths:
for path in / /web-index.html /does-not-exist; do echo "=== $path ===" curl -sS --max-time 5 -o /dev/null \ -w 'HTTP=%{http_code}\n' "http://127.0.0.1:6768$path" done
Observed results: all three time out and print
HTTP=000(no HTTP status/headers), including/does-not-exist. -
Changing the
Hostheader tolocalhost:6768,127.0.0.1:6768, ororcanew:6768does not change the result.
Expected vs. actual behavior
Expected: With a shipped web bundle, the public orca serve HTTP endpoint serves the browser client (GET / returns HTTP 200 HTML) and prints its Web client URL; invalid routes should receive an HTTP response (such as 404), not remain pending.
Actual: The public endpoint accepts TCP connections but responds to none of the tested HTTP GET requests. Runtime pairing starts and the terminal daemon self-test passes. No browser URL is printed.
Evidence: the web assets and internal Electron HTTP server work
The installed web index file exists:
/opt/Orca/resources/app.asar.unpacked/out/web/web-index.html
-rw-r--r-- 1 root root 2076 Oct 17 08:18 .../web-index.html
Process and listening-port inspection during one run showed:
orcad-server.js --bind 0.0.0.0 --port 6768 --pairing-address http://127.0.0.1:6768
listening on 0.0.0.0:6768
/opt/Orca/orca-ide --serve --serve-port --serve-json --serve-no-pairing \
--ozone-platform=x11 --user-data-dir=/tmp/orcad-browser-... 40241
listening on 0.0.0.0:40241 and 127.0.0.1:44685
These internal ports are dynamically allocated and are examples only.
curl -v --max-time 5 http://127.0.0.1:40241/returned:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 2076
Cache-Control: no-cache
with HTML titled Orca Web. A request to the other internal port, 44685, returned HTTP/1.1 404 Not Found. Therefore, the packaged HTML is readable and the internal Electron web server is responsive. This does not itself establish how the public orcad endpoint is meant to connect to it.
On the original Ubuntu host, a WebSocket Upgrade request to /ws returned HTTP/1.1 101 Switching Protocols. This handshake demonstrates that the upgrade path was responsive there; it does not establish full WebSocket functionality.
Code-level hypothesis (not yet proven)
In the installed, minified orcad-server.js, the runtime constructor accepts webClientRoot, saves it as this.webClientRoot, and supplies it as staticRoot to its WebSocket/HTTP transport. The HTTP server factory appears equivalent to:
createHttpServer() {
const handler = this.staticRoot
? createStaticHandler(this.staticRoot)
: undefined;
return http.createServer(handler);
}(createStaticHandler is a descriptive placeholder for the minified function qVs; this is a readable paraphrase, not verbatim source.)
Node's http.createServer(undefined) can accept connections without installing a request listener. Unless another listener is registered, ordinary HTTP requests would remain unanswered. In the same bundled code, webClientUrl is conditionally generated only when this.webClientRoot is set and the scope is runtime.
Hypothesis: webClientRoot is not supplied to the public orcad process in this headless Linux startup path. That would explain both the absent browser URL and the HTTP requests that hang. The actual runtime value of webClientRoot has not been measured, so this is not a confirmed root cause. The string search of the installed CLI bundle (out/cli/index.js) found no literal webClientRoot or staticRoot, but this is not definitive evidence of a missing handoff.
There is no documented --web-root/--static-root option in orca-ide serve --help to set the root explicitly.
Comparisons and workarounds
| Environment | Observation |
|---|---|
| Original headless Ubuntu host, v1.4.217, same host configuration | GET / returned HTTP 200 |
| Original headless Ubuntu host, v1.4.229 | GET / hung without response |
| Fresh Ubuntu 24.04.5 headless LXC, v1.4.229 | GET /, /web-index.html, and /does-not-exist all timed out |
| Fresh LXC, v1.4.229, internal Electron endpoint | GET / returned HTTP 200 with web HTML |
| Local macOS installation (as reported in the same investigation) | GET / returned HTTP 200; version was not independently confirmed in the supplied curl output |
On the original headless system, both a manual systemd setup and orca-ide serve service install reportedly exhibited the problem. On the fresh LXC it reproduces without systemd.
Creating a diagnostic symlink from /opt/Orca/resources/web to /opt/Orca/resources/app.asar.unpacked/out/web did not resolve the issue. Running with software rendering and the disabled Electron sandbox did not resolve it either.
Related changes / reports
- PR fix(web): the paired server is the web client's only host #27266, “The paired server is the web client's only host”: fix(web): the paired server is the web client's only host #27266
- PR fix(serve): ship the paired web client outside app.asar so a /tmp sweep cannot break it #29277, “Ship the paired web client outside app.asar …”: fix(serve): ship the paired web client outside app.asar so a /tmp sweep cannot break it #29277
- Issue [Bug]:
orca serveweb client answers an empty 500 after its /tmp asar extracts are cleaned up #27976: [Bug]:orca serveweb client answers an empty 500 after its /tmp asar extracts are cleaned up #27976 - Issue Self-hosted ADE: ship the web client standalone, and make remote server install one command #10687: Self-hosted ADE: ship the web client standalone, and make remote server install one command #10687
These are areas worth reviewing, not confirmed causes.
Questions for maintainers
- How should
webClientRootbe resolved and propagated to the separateorcadprocess when startingorca-ide serveheadlessly on Linux? - Can this path leave
staticRootunset while still binding the public HTTP socket? - Should the HTTP server return an explicit error (404/503) when no web handler is configured, instead of leaving requests pending?
- Is there a supported browser-only headless Linux deployment procedure specific to v1.4.229 that differs from the steps above?
Security note: The pairing code, device tokens, and other secrets are intentionally redacted. Please do not request raw pairing URLs in public comments.
Activity
fix(serve): orca serve on orcad serves the browser client and answers…
fix(serve): orca serve on orcad serves the browser client and answers…
nwparker commentedon Oct 17, 2026
Thanks for the report — this was a real regression in v1.4.229. Since #26374,
orca serveruns on orcad by default, and orcad was never given the web client's location, so plain HTTP requests were accepted but never answered (WebSocket upgrades still worked). Fixed in #30120: the CLI now hands orcad the bundled web client, a server without a web client answers 404 instead of hanging, and packaging fails if the web client is missing. It ships in the next release.