Skip to content

[Multi Platforms][Onboard] Ollama daemon and :11435 proxy inherit host HTTP_PROXY without injecting NO_PROXY=localhost — localhost inference fails through user proxy (e.g. Privoxy) #2616

@hulynn

Description

@hulynn

Description

Description
NemoClaw spawns the Ollama daemon and the NemoClaw-managed :11435 auth proxy without sanitizing host HTTP_PROXY/http_proxy environment variables. When the user's machine has a host-level proxy set — common for any developer running Cursor / Claude Desktop / corporate Brev CLI configurations that rely on Privoxy at 127.0.0.1:8118 — the spawned subprocesses inherit
HTTP_PROXY but receive no NO_PROXY=localhost,127.0.0.1 hint.
Result:
localhost-only traffic between sandbox -> :11435 -> Ollama 11434 is routed through Privoxy, which either rejects or 500-errors the loopback URL, breaking inference end-to-end.

Source evidence (NemoClaw v0.0.28):

1) dist/lib/subprocess-env.js:26 explicitly allow-lists proxy env vars
for forwarding to all subprocesses — by design:

 const PROXY = ["HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY",
                "http_proxy", "https_proxy", "no_proxy"];
  1. dist/lib/onboard-ollama-proxy.js:204-209 spawns ollama pull with full
    parent env (no buildSubprocessEnv filter, no NO_PROXY injection):

    spawnSync("bash", ["-c", ollama pull ${shellQuote(model)}], {
    ...
    env: { ...process.env }, ← full inheritance
    });

  2. dist/lib/onboard-ollama-proxy.js:88 spawns the NemoClaw auth proxy
    (the :11435 proxy) — also NO injection of NO_PROXY=localhost.

I grep'd the entire dist/ directory: there is NO code path that injects NO_PROXY=localhost,127.0.0.1 for the spawned Ollama daemon, the :11435 NemoClaw auth proxy, or the model-pull subprocess. localhost traffic is unconditionally forwarded through the user's HTTP_PROXY.

Why this is NemoClaw's responsibility (not the user's):

  • The :11435 auth proxy is spawned BY NemoClaw (ollama-auth-proxy.js).
    NemoClaw fully controls that subprocess's env.
  • Ollama's own daemon respects NO_PROXY=localhost,127.0.0.1 if set —
    NemoClaw just has to pass it on the spawn call.
  • Standard convention (RFC 7230 / curl / wget / Go HTTP client default
    with NO_PROXY) is that loopback addresses should NOT go through HTTP_PROXY.
  • Once the daemon is spawned with the polluted env, env changes in the
    user's shell (launchctl unsetenv, unset http_proxy, etc.) have NO
    effect — env is baked into the live daemon. End-user can't recover
    without env -i + restart all daemons.

User-visible failure mode (verbatim from a real session):

✗ Local Ollama endpoint validation failed.
HTTP 500 — Internal Privoxy Error
Privoxy could not connect to the host: 127.0.0.1:11435

(The 11435 proxy that NemoClaw itself spawned, talking to localhost,
is being routed back through the user's host Privoxy.)

Population of affected developers:

  • Cursor users (Privoxy commonly bundled)
  • Claude Desktop users (sometimes bundled)
  • Anthropic / OpenAI dogfood users behind corporate proxy
  • ALL NV employees with the standard internal proxy stack

In other words: ~100% of internal dogfood users hit this.

Environment

Device:        MacBook (Apple M4)
OS:            macOS (recent)
Architecture:  arm64
Node.js:       Not captured
npm:           Not captured
Docker:        Not captured
OpenShell CLI: openshell 0.0.36
NemoClaw:      v0.0.28
OpenClaw:      Not reached (Ollama validation fails before sandbox creation)

Reproducing host config:
  http_proxy=http://127.0.0.1:8118        # set at user-shell or launchctl level
  HTTP_PROXY=http://127.0.0.1:8118
  (no NO_PROXY set, or NO_PROXY does not include 127.0.0.1)

Source ref: NemoClaw v0.0.28 dist/.
Steps to Reproduce
1. On a macOS host where Privoxy (or any host-level HTTP proxy) is running
   on 127.0.0.1:8118 and the user has it exported in their shell:

     export http_proxy=http://127.0.0.1:8118
     export HTTP_PROXY=http://127.0.0.1:8118
     # NO_PROXY intentionally NOT set

2. Onboard NemoClaw v0.0.28, pick Local Ollama:

     nemoclaw onboard
     # Provider [1]: 7   (Local Ollama)
     # Pick any model

3. Watch the [3/8] inference setup step. The Ollama endpoint validation
   fails:

     ✗ Local Ollama endpoint validation failed.
     HTTP 500 — Internal Privoxy Error
     Privoxy could not connect to the host: 127.0.0.1:11435

4. Try the obvious workarounds; none work:
     - unset HTTP_PROXY  (doesn't unset the lowercase one)
     - unset http_proxy  (clears shell, but the already-spawned ollama
                          daemon and :11435 proxy still have polluted env)
     - launchctl unsetenv http_proxy  (same: doesn't affect live daemons)

5. Only `env -i ... ollama serve` from a clean shell, plus killing and
   restarting any spawned :11435 process, recovers. Most users won't know
   to do this.
Expected Result
NemoClaw should inject `NO_PROXY=localhost,127.0.0.1,*.local` (and the
lowercase `no_proxy` for completeness) into the env of every subprocess
it spawns that is expected to reach a localhost target. At minimum:
- ollama serve  (NemoClaw's spawn of the daemon during onboard)
- ollama pull   (in pullOllamaModel)
- the NemoClaw-managed auth proxy on :11435 (ollama-auth-proxy.js spawn)

After the fix:
- Onboard works on Privoxy-equipped Macs out of the box.
- Localhost traffic for Ollama (sandbox -> :11435 -> 127.0.0.1:11434)
  bypasses the user's host proxy.
- User's outbound HTTP_PROXY for non-localhost URLs (registry.ollama.ai
  during ollama pull) is still respected.
Actual Result
Spawned subprocesses inherit HTTP_PROXY/http_proxy from the user's shell without any NO_PROXY=localhost,127.0.0.1 injection. Localhost traffic goes through Privoxy, which 500s because the user's Privoxy isn't configured to forward loopback.

User sees:
  Local Ollama endpoint validation failed.
  HTTP 500 — Internal Privoxy Error

Even after the user manually clears http_proxy in their shell, the already-spawned daemons (Ollama, :11435 proxy) retain the polluted env because env is captured at spawn time. The fix path for an end-user is non-trivial and undocumented (env -i + restart all daemons).

Confirmed in source: dist/lib/subprocess-env.js:26 forwards proxy env; dist/lib/onboard-ollama-proxy.js:204-209 and :88 spawn without injecting NO_PROXY for loopback. No NO_PROXY=localhost injection found anywhere in dist/.
Logs
Source files inspected (NemoClaw v0.0.28):
  dist/lib/subprocess-env.js          — allow-lists PROXY env names
  dist/lib/onboard-ollama-proxy.js:88 — spawn auth proxy, no NO_PROXY
  dist/lib/onboard-ollama-proxy.js:204 — spawn ollama pull, env: {...process.env}

Related context (not duplicates, just adjacent):
- NVBug 6045023 ([macOS][Ollama] Local Ollama inference hangs through NemoClaw/OpenShell routing) — different symptom (hang, not 500), but same general "Ollama-on-mac inference path is fragile" theme.

Bug Details

Field Value
Priority Unprioritized
Action Dev - Open - To fix
Disposition Open issue
Module Machine Learning - NemoClaw
Keyword NemoClaw, NEMOCLAW_GH_SYNC_APPROVAL, NemoClaw_Onboard, NemoClaw-SWQA-RelBlckr-Recommended, NemoClaw-SWQA-VDR

[NVB#6122435]

Metadata

Metadata

Labels

NV QABugs found by the NVIDIA QA TeamUATIssues flagged for User Acceptance Testing.area: cliCommand line interface, flags, terminal UX, or outputarea: inferenceInference routing, serving, model selection, or outputsarea: local-modelsLocal model providers, downloads, launch, or connectivityarea: providersInference provider integrations and provider behaviorprovider: ollamaOllama local model provider behaviorv0.0.46Release target
No fields configured for Enhancement.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions