Skip to content

[Bug]: Linux headless: orca serve v1.4.229 accepts WebSocket connections but HTTP requests hang indefinitely (possible missing webClientRoot) #30100

Closed

Description

@buzzzerde

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 via apt.
  • 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 DISPLAY set in the shell or inspected Electron process; an Orca-launched Xvfb :99 process was observed.

Reproduction steps

  1. 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
  2. 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 404
    

    No Web client URL appears, although orca-ide serve --help documents that one is printed when the bundle is available. The agent-state-rules 404 may be unrelated.

  3. 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
    
  4. 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.

  5. Changing the Host header to localhost:6768, 127.0.0.1:6768, or orcanew:6768 does 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

These are areas worth reviewing, not confirmed causes.

Questions for maintainers

  1. How should webClientRoot be resolved and propagated to the separate orcad process when starting orca-ide serve headlessly on Linux?
  2. Can this path leave staticRoot unset while still binding the public HTTP socket?
  3. Should the HTTP server return an explicit error (404/503) when no web handler is configured, instead of leaving requests pending?
  4. 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

  1. added theissue type on Oct 17, 2026
  2. nwparker commented on Oct 17, 2026

    @nwparker
    Contributor

    Thanks for the report — this was a real regression in v1.4.229. Since #26374, orca serve runs 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingos:linuxIssues affecting Linux

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions