Skip to content

NemoClaw sandbox: Gemini web_search fails with EAI_AGAIN until Google host + node are allowed, and trusted proxy still does local DNS lookup #396

@alannguyen1

Description

@alannguyen1

NemoClaw sandbox: Gemini web_search fails with getaddrinfo EAI_AGAIN until Google host + node are allowed, and OpenClaw trusted proxy path still performs local DNS lookup

Environment

  • Host: macOS Apple Silicon
  • Runtime: Docker Desktop
  • NemoClaw: current upstream install on 2026-03-19
  • Sandbox: my-assistant
  • OpenClaw in sandbox: 2026.3.11 (29dc654)
  • Inference: NVIDIA managed route via inference.local
  • Web search provider: Gemini / Google Search grounding

Summary

Gemini-backed web_search inside a NemoClaw sandbox repeatedly failed with:

[tools] web_search failed: getaddrinfo EAI_AGAIN generativelanguage.googleapis.com

The same Gemini key worked from the host machine, and later also worked from inside the sandbox with a direct node test once the networking path was fixed.

This turned out to be a stacked issue:

  1. the default NemoClaw sandbox policy did not allow generativelanguage.googleapis.com
  2. the relevant policy binaries lists did not include /usr/local/bin/node, even though openclaw runs via #!/usr/bin/env node
  3. OpenClaw's trusted env proxy path still does a local pinned DNS lookup before creating EnvHttpProxyAgent, which defeats the proxy path in a sandbox and produces EAI_AGAIN
  4. the background gateway used by openclaw tui had to be restarted after patching, otherwise TUI kept using the old broken gateway process

Repro

  1. Set up NemoClaw on macOS with Docker Desktop and NVIDIA cloud inference.
  2. Inside the sandbox, configure web search with Gemini in ~/.openclaw/openclaw.json.
  3. Run:
openclaw agent --agent main --local -m "Use the web_search tool to search for the OpenClaw documentation homepage and answer with only the homepage URL." --session-id webtest-1

or:

openclaw tui

Then ask the agent to use web_search.

Observed result:

[tools] web_search failed: getaddrinfo EAI_AGAIN generativelanguage.googleapis.com

Diagnosis

A. Default NemoClaw policy is missing the Gemini endpoint

The stock template includes NVIDIA/OpenClaw/GitHub/npm/Telegram endpoints, but not:

  • generativelanguage.googleapis.com

That means Gemini web search cannot work through the sandbox's egress policy without additional allowlisting.

B. Policy matching is binary-path based, but openclaw executes as node

Inside the sandbox:

command -v openclaw
ls -l /usr/local/bin/openclaw
command -v node

/usr/local/bin/openclaw is a launcher script using #!/usr/bin/env node, so the real executable path is:

  • /usr/local/bin/node

Allowing /usr/local/bin/openclaw alone is not enough for all proxy/policy decisions.

C. OpenClaw trusted env proxy path still resolves DNS locally first

In the installed OpenClaw build, fetch-guard-CBQYpTN6.js does:

const pinned = await resolvePinnedHostnameWithPolicy(parsedUrl.hostname, {
  lookupFn: params.lookupFn,
  policy: params.policy
});
if (mode === GUARDED_FETCH_MODE.TRUSTED_ENV_PROXY && hasProxyEnvConfigured()) {
  dispatcher = new EnvHttpProxyAgent();
} else if (params.pinDns !== false) {
  dispatcher = createPinnedDispatcher(pinned);
}

So even in TRUSTED_ENV_PROXY mode, it still performs a local DNS lookup before using the proxy. In the sandbox, that causes the EAI_AGAIN failure.

Local Workaround That Worked

1. Expand the sandbox policy

Add:

  • generativelanguage.googleapis.com:443

and add /usr/local/bin/node to the relevant binaries lists used by OpenClaw/Gemini traffic.

2. Patch OpenClaw fetch guard logic

Skip the local pinned DNS lookup when using TRUSTED_ENV_PROXY mode, and create EnvHttpProxyAgent() first.

Local patch:

const useTrustedEnvProxy = mode === GUARDED_FETCH_MODE.TRUSTED_ENV_PROXY && hasProxyEnvConfigured();
if (useTrustedEnvProxy) dispatcher = new EnvHttpProxyAgent();
else {
  const pinned = await resolvePinnedHostnameWithPolicy(parsedUrl.hostname, {
    lookupFn: params.lookupFn,
    policy: params.policy
  });
  if (params.pinDns !== false) dispatcher = createPinnedDispatcher(pinned);
}

3. Restart the gateway under the patched runtime

The TUI uses the long-running background gateway. After patching, that process needed to be restarted or TUI kept failing with the old runtime.

Verification

After applying the workaround, this direct sandbox test succeeded:

node - <<'JS'
const fs = require("fs");
const cfg = JSON.parse(fs.readFileSync("/sandbox/.openclaw/openclaw.json", "utf8"));
fetch("https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-goog-api-key": cfg.tools.web.search.gemini.apiKey
  },
  body: JSON.stringify({
    contents: [{ parts: [{ text: "Who is the current president of France? Return only the name." }] }],
    tools: [{ google_search: {} }]
  })
}).then(async r => console.log(r.status, await r.text()));
JS

This returned 200 and included groundingMetadata.

Also, one-shot OpenClaw search succeeded:

openclaw agent --agent main --local -m "Use the web_search tool to search for the OpenClaw documentation homepage and answer with only the homepage URL." --session-id webtest-1

Observed output:

https://docs.openclaw.ai

Suggestions

  1. Add a documented NemoClaw policy preset for Gemini / Google Search grounding.
  2. Include /usr/local/bin/node anywhere openclaw is expected to make outbound calls.
  3. Change OpenClaw TRUSTED_ENV_PROXY fetch mode so it does not require local pinned DNS lookup before using EnvHttpProxyAgent.
  4. Consider documenting that TUI may need a gateway restart after runtime patching, otherwise old failures persist.

Related

Would maintainers prefer:

  • a docs PR for the Gemini web-search policy requirements, or
  • a code fix directly in OpenClaw / NemoClaw for the trusted proxy path and policy defaults?

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: sandboxOpenShell sandbox lifecycle, runtime, config, or recoveryplatform: macosAffects macOS, including Apple Silicon

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions