openclaw - ✅(Solved) Fix [Bug]: memory_search remote embeddings fail with ENOTFOUND when env proxy is configured — withRemoteHttpResponse skips TRUSTED_ENV_PROXY mode [7 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#52162Fetched 2026-04-08 01:14:57
View on GitHub
Comments
2
Participants
3
Timeline
8
Reactions
0
Author
Timeline (top)
cross-referenced ×4commented ×2referenced ×2

withRemoteHttpResponse() in the memory remote embeddings path does not check hasProxyEnvConfigured() before calling fetchWithSsrFGuard(), causing it to default to strict mode which performs local DNS pre-resolution via resolvePinnedHostnameWithPolicy(). In proxy environments (e.g. Clash TUN/fake-IP, corporate proxies), this DNS lookup fails with getaddrinfo ENOTFOUND before the request ever reaches the proxy, even though proxy-routed requests via the OpenAI SDK succeed on the same machine.

Error Message

Error: getaddrinfo ENOTFOUND api.ohmygpt.com

Root Cause

The same proxy + endpoint combination works when OpenClaw makes regular OpenAI SDK calls (e.g. chat completions), because those paths correctly use proxy-aware fetch. Only the memory embeddings path fails.

Fix Action

Fix / Workaround

Workaround: Manually patch withRemoteHttpResponse() in the affected dist bundles to add the hasProxyEnvConfigured() check as shown above.

PR fix notes

PR #52191: fix(memory): apply env proxy guard to withRemoteHttpResponse

Description (problem / solution / changelog)

Summary

  • Problem: withRemoteHttpResponse() calls fetchWithSsrFGuard() without setting a mode, defaulting to STRICT. In strict mode, local DNS pre-resolution via dns.lookup() runs before the HTTP request, which fails with getaddrinfo ENOTFOUND in proxy environments where DNS must go through the proxy.
  • Why it matters: Memory embeddings are completely unusable for users behind HTTP proxies (Clash TUN fake-IP, corporate proxies with DNS-over-proxy), even though all other proxy-aware code paths work correctly on the same machine.
  • What changed: withRemoteHttpResponse() now checks hasProxyEnvConfigured() and, when true, wraps fetch options with withTrustedEnvProxyGuardedFetchMode() so fetchWithSsrFGuard() uses EnvHttpProxyAgent instead of pinned DNS.
  • What did NOT change: Non-proxy environments still get the default strict SSRF guard behavior. No changes to fetchWithSsrFGuard() itself, SSRF policy, or any other code path.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #52162

User-visible / Behavior Changes

openclaw memory status --deep and openclaw memory search now work correctly when environment proxy variables (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY) are configured and local DNS cannot resolve the embedding provider hostname.

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No — same fetchWithSsrFGuard is used, only the mode changes from STRICT to TRUSTED_ENV_PROXY when env proxy is detected, which is the same pattern already used by fetchWithWebToolsNetworkGuard in src/agents/tools/web-guarded-fetch.ts.
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Windows 11 Pro 10.0.22631
  • Runtime: Node.js via npm global install
  • Model/provider: openai/text-embedding-3-small (remote OpenAI-compatible endpoint)
  • Relevant config: HTTPS_PROXY=http://127.0.0.1:7890 (Clash TUN with fake-IP mode)

Steps

  1. Configure HTTPS_PROXY env var pointing to an HTTP proxy
  2. Use a proxy setup where local DNS cannot resolve the embedding provider hostname (e.g. Clash TUN fake-IP)
  3. Run openclaw memory status --deep --agent main

Expected

Embeddings status shows as available

Actual (before fix)

getaddrinfo ENOTFOUND <hostname> — Embeddings: unavailable

Evidence

  • Trace/log snippets — see issue #52162 for full reproduction logs
  • Failing test/log before + passing after — existing unit tests pass (post-json.test.ts, embeddings-remote-fetch.test.ts); TypeScript type check passes

Human Verification (required)

  • Verified scenarios: Code review confirmed the fix follows the exact same pattern as fetchWithWebToolsNetworkGuard in src/agents/tools/web-guarded-fetch.ts (line 46-48). Unit tests and type check pass.
  • Edge cases checked: When no proxy env is configured, hasProxyEnvConfigured() returns false and behavior is unchanged (default strict mode).
  • What you did not verify: End-to-end test in a Clash TUN environment (do not have the setup in CI). Manual verification by the reporter would be appreciated.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery (if this breaks)

  • How to revert: Revert the single commit; withRemoteHttpResponse() goes back to calling fetchWithSsrFGuard() without a mode.
  • Known bad symptoms: If TRUSTED_ENV_PROXY mode somehow causes issues, embedding requests may fail differently (proxy errors instead of DNS errors). Reverting restores previous behavior.

Risks and Mitigations

  • Risk: In TRUSTED_ENV_PROXY mode, SSRF DNS pinning is bypassed for the embedding endpoint when a proxy is configured, relying on the proxy for network-level access control.
    • Mitigation: This is the same trade-off already accepted for web tool fetches (web-guarded-fetch.ts). The SSRF policy (allowed hostnames from buildRemoteBaseUrlPolicy) is still validated by resolvePinnedHostnameWithPolicy before the mode branch. The proxy itself provides the network boundary.

This PR was prepared with AI assistance (Claude Code). The change was code-reviewed and the pattern was verified against the existing proxy-aware code path in web-guarded-fetch.ts.

Changed files

  • packages/memory-host-sdk/src/host/remote-http.ts (modified, +10/-3)

PR #59007: fix(net): skip DNS pinning before trusted env proxy dispatch

Description (problem / solution / changelog)

Summary

Fixes fetchWithSsrFGuard() so trusted env-proxy mode can actually reach EnvHttpProxyAgent before any local DNS lookup is attempted.

This fixes the remaining proxy-only sandbox failure tracked in #59005. It is the same production gap described in #58034, but rebased cleanly on current main and with the fallback test tightened so host ALL_PROXY / all_proxy values cannot accidentally satisfy the proxy branch.

What changed

  • move DNS pinning and pinned-dispatcher creation into the non-proxy branch
  • keep trusted env-proxy dispatch as an early branch
  • clear all six proxy env keys in the tests before setting expectations
  • add an explicit regression test for trusted mode with no proxy env vars present

Why

#50650 fixed the strict-mode env-proxy path, but both main and v2026.3.31 still resolve DNS before entering the trusted env-proxy branch:

const pinned = await resolvePinnedHostnameWithPolicy(...);
const canUseTrustedEnvProxy =
  mode === GUARDED_FETCH_MODE.TRUSTED_ENV_PROXY && hasProxyEnvConfigured();
if (canUseTrustedEnvProxy) {
  dispatcher = new EnvHttpProxyAgent();
}

In proxy-only sandboxes, that ordering means the request fails on local DNS and never reaches the trusted proxy.

Testing

  • pnpm exec vitest run --config vitest.unit.config.ts src/infra/net/fetch-guard.ssrf.test.ts
  • pnpm check

Notes

  • Fixes #59005
  • Supersedes #58034

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/infra/net/fetch-guard.ssrf.test.ts (modified, +38/-0)
  • src/infra/net/fetch-guard.ts (modified, +4/-4)

PR #64095: Fix proxy fetch propagation for Gemini memory embeddings

Description (problem / solution / changelog)

Summary

  • thread the resolved proxy-aware fetchImpl through Gemini memory embedding HTTP calls
  • forward fetchImpl via withRemoteHttpResponse() in the memory host SDK package source
  • keep the mirrored src/memory-host-sdk Gemini call sites aligned

Why

In the Gemini memory embedding path, resolveGeminiEmbeddingClient() already resolves a proxy-aware fetchImpl, but the actual Gemini request call sites were not passing that fetch implementation into withRemoteHttpResponse(...).

That means the client could be configured for env-proxy fetch, while the real HTTP calls still fell back to the default fetch path. In proxy-only / China / corporate-proxy environments this can surface as direct Google connection timeouts in memory_search even though other proxy-aware paths work.

This showed up locally as:

  • memory_search returning disabled/unavailable
  • fetch failed | Connect Timeout Error (... 142.250.x.x:443 ...)
  • immediate recovery after patching these call sites in the installed build

Scope

This PR updates the Gemini memory embedding request path for:

  • direct embed requests
  • Gemini batch upload
  • Gemini batch create
  • Gemini batch status polling
  • Gemini batch download

Testing

  • Local runtime validation on an installed 2026.4.9 build: patched equivalent dist call sites and confirmed memory_search recovered
  • Repo test run not completed here because this fresh clone does not have repo dependencies installed yet (vitest/package.json missing)

Closes or advances: #52162

Changed files

  • packages/memory-host-sdk/src/host/batch-gemini.ts (modified, +4/-0)
  • packages/memory-host-sdk/src/host/embeddings-gemini.ts (modified, +12/-1)
  • packages/memory-host-sdk/src/host/embeddings.ts (modified, +1/-0)
  • packages/memory-host-sdk/src/host/post-json.ts (modified, +2/-0)
  • packages/memory-host-sdk/src/host/remote-http.ts (modified, +2/-0)
  • src/memory-host-sdk/host/batch-gemini.ts (modified, +4/-0)
  • src/memory-host-sdk/host/embeddings-gemini.ts (modified, +12/-1)
  • src/memory-host-sdk/host/embeddings.types.ts (modified, +1/-0)

PR #64974: fix(media-understanding): auto-upgrade provider HTTP helper to trusted env proxy mode

Description (problem / solution / changelog)

Summary

Auto-upgrades the provider HTTP helper fetchWithTimeoutGuarded in src/media-understanding/shared.ts to GUARDED_FETCH_MODE.TRUSTED_ENV_PROXY when hasProxyEnvConfigured() returns true and the caller did not pass an explicit mode. Also adds an optional mode parameter so callers that need strict pinned-DNS can still opt back in.

Refs #52162.

Why

Image, music, video, and audio generation providers all route through postJsonRequest / postTranscriptionRequest in shared.ts, which call fetchWithTimeoutGuarded, which calls fetchWithSsrFGuard without a mode. That falls through to STRICT, which forces a Node-level dns.lookup() pre-resolution of the target hostname before dialing the configured proxy.

In HTTP-proxy-only environments — containers, restricted sandboxes, corporate networks with DNS-over-proxy, Clash TUN fake-IP — that local DNS lookup fails with EAI_AGAIN or ENOTFOUND before the request ever reaches the proxy. The observed symptoms:

  • Image generation: EAI_AGAIN api.minimax.io / ENOTFOUND api.openai.com from image-generation-provider-*.js
  • Audio transcription: ENOTFOUND api.openai.com from the postTranscriptionRequest path
  • Music / video generation: same DNS error class
  • Memory embeddings (openclaw#52162): ENOTFOUND api.ohmygpt.com via withRemoteHttpResponse / Gemini embedding path

LLM chat completions to the same hosts work fine in these environments because they inherit undici's global dispatcher (typically set to EnvHttpProxyAgent by a bootstrap preload). Only the media / provider HTTP paths are affected.

Change scope

  • Only fetchWithTimeoutGuarded in src/media-understanding/shared.ts is touched.
  • fetchWithSsrFGuard and src/infra/net/fetch-guard.ts are unchanged — lower-level callers keep their existing STRICT default.
  • No default behavior change when no HTTP proxy is configured in the environment (the auto-upgrade is gated on hasProxyEnvConfigured()).
  • Callers that explicitly need strict pinned-DNS can still opt in by passing mode: "strict" or by calling fetchWithSsrFGuard directly.

Security rationale

When an HTTP CONNECT proxy sits in the egress path, the proxy itself performs hostname resolution and can rewrite traffic to any destination, so client-side DNS pinning does not meaningfully constrain the target IP anyway. Moving provider HTTP calls to TRUSTED_ENV_PROXY mode in those environments restores functionality without weakening the protection DNS pinning actually provides — SSRF posture in direct-egress setups (no HTTP_PROXY env) is unchanged because hasProxyEnvConfigured() returns false and the code path is identical to today's.

Tests

Four new vitest cases in src/media-understanding/shared.test.ts mock both fetchWithSsrFGuard and hasProxyEnvConfigured:

  1. no-op when no proxy env — ensures mode is not set on the guard call when hasProxyEnvConfigured() returns false
  2. auto-upgrade on postJsonRequest — asserts mode: "trusted_env_proxy" is set when hasProxyEnvConfigured() returns true
  3. caller mode: "strict" override respected — asserts the caller-supplied mode wins over the auto-upgrade
  4. transcription-request path auto-upgrades — ensures postTranscriptionRequest also gets the upgrade (verifying the shared helper covers all call sites, not just JSON)

Test plan

  • pnpm exec vitest run src/media-understanding/shared.test.ts — 15/15 pass (11 existing + 4 new)
  • pnpm exec vitest run src/infra/net/fetch-guard.ssrf.test.ts — 39/39 pass (no adjacent regression)
  • oxlint clean on both touched files
  • oxfmt clean on both touched files
  • CI typecheck on the full repo (relies on PR CI; local pnpm check had unrelated type errors in src/gateway/server-channels.test.ts and src/plugin-sdk/channel-runtime-context.ts already present on current main head at 462d8e3b fix(cycles): narrow channel runtime surface)
  • End-to-end verified: with the equivalent dist-level patch applied to a sandbox running 2026.4.11-beta.1, minimax/image-01 generates successfully through api.minimax.io/v1/image_generation over an HTTP CONNECT proxy, returning a real image. Without the patch, the same call fails with EAI_AGAIN before hitting the proxy.

Happy to rebase / split / narrow further if the maintainers would prefer a different shape. The core one-line behavior change is the resolvedMode ternary; the rest is documentation and tests.

Changed files

  • src/infra/net/proxy-env.test.ts (modified, +140/-0)
  • src/infra/net/proxy-env.ts (modified, +104/-0)
  • src/media-understanding/shared.test.ts (modified, +223/-4)
  • src/media-understanding/shared.ts (modified, +108/-3)

PR #54959: docs: add OpenShell deployment guide

Description (problem / solution / changelog)

Summary

Add a comprehensive deployment guide for running OpenClaw inside NVIDIA OpenShell sandboxes.

The guide covers:

  • Prerequisites and quick start with the automated setup script
  • Manual step-by-step setup — Docker, gateway, sandbox creation, CoreDNS fix, OpenClaw bundling, Slack configuration
  • Network policy — policy structure, the Slack REST/WebSocket split, why *.slack.com wildcards break Socket Mode on v0.0.15+, tls: skip for WebSocket raw TCP passthrough
  • WebSocket proxy patch — why the ws library doesn't honor HTTPS_PROXY, the Module._load monkey-patch solution, applicability to Discord gateway connections
  • Troubleshooting — DNS failures, WebSocket issues, bot ignoring DMs, npm hangs, gateway corruption
  • Known limitations — web_fetch/web_search proxy issues, binary identification requirements

Also adds the new page to the Platforms tab in docs.json navigation.

Related issues

This addresses the documentation gap for sandboxed/proxied deployments. Related issues reporting proxy, WebSocket, and DNS failures in sandboxed environments:

  • #49948 — web_fetch proxy issues
  • #47598 — WebSocket connection failures
  • #46306 — web_search proxy errors
  • #50655 — DNS resolution failures in sandboxed environments
  • #44980 — proxy configuration issues
  • #51049 — sandbox networking problems

Changed files

  • docs/.i18n/glossary.zh-CN.json (modified, +28/-0)
  • docs/docs.json (modified, +2/-1)
  • docs/platforms/openshell.md (added, +836/-0)

PR #66458: fix(media-understanding): auto-upgrade provider HTTP helper to trusted env proxy mode

Description (problem / solution / changelog)

Summary

  • problem: provider HTTP helper requests still forced strict SSRF DNS pinning in proxy-only environments, so remote media-understanding and transcription paths could fail with local ENOTFOUND / EAI_AGAIN before the configured proxy ever saw the request
  • root cause: src/media-understanding/shared.ts called fetchWithSsrFGuard() without selecting trusted_env_proxy mode for env-proxy cases, and there was no shared NO_PROXY matcher to keep the auto-upgrade from bypassing strict mode on direct-bypass targets
  • fix: auto-upgrade only the safe env-proxy cases, preserve strict mode when NO_PROXY bypasses the target or a caller supplies explicit dispatcher policy, and add focused coverage for the proxy-env matcher plus the guarded helper behavior

Fixes #52162. Related #66245. Supersedes #64974.

Verification

  • pnpm test:serial src/media-understanding/shared.test.ts src/infra/net/proxy-env.test.ts src/infra/net/fetch-guard.ssrf.test.ts
  • pnpm build

Changelog

  • added unreleased fix entry with Thanks @mjamiv and @vincentkoc

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/infra/net/proxy-env.test.ts (modified, +140/-0)
  • src/infra/net/proxy-env.ts (modified, +104/-0)
  • src/media-understanding/shared.test.ts (modified, +223/-4)
  • src/media-understanding/shared.ts (modified, +108/-3)

PR #66461: fix(telegram): trust explicit proxy DNS for media downloads

Description (problem / solution / changelog)

Summary

  • Problem: Telegram media downloads still force local target DNS resolution even when the channel is configured with an explicit HTTP proxy.
  • Why it matters: proxy-backed installs regress with could not download media on Bot API file downloads because the proxy is supposed to resolve Telegram CDN hostnames, not the local sandbox.
  • What changed: added a trusted explicit-proxy guarded-fetch mode that keeps hostname-policy checks but skips local target DNS pinning, then wired Telegram media downloads to opt into that path.
  • What did NOT change (scope boundary): env-proxy behavior, generic direct-fetch SSRF policy, and Telegram text/API request routing outside the media download path.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #66245
  • Related #52162
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: src/media/fetch.ts always wrapped media downloads in strict guarded-fetch mode, so explicit Telegram proxy dispatcher policies still ran resolvePinnedHostnameWithPolicy() on the target hostname before dialing the proxy.
  • Missing detection / guardrail: there was no regression coverage for explicit-proxy media downloads that must preserve hostname allowlists while skipping local target DNS resolution.
  • Contributing context (if known): #52162 fixed the env-proxy variant for provider HTTP helpers, but Telegram media downloads use explicit proxy dispatchers on a different path.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/infra/net/fetch-guard.ssrf.test.ts, src/media/fetch.test.ts, extensions/telegram/src/bot/delivery.resolve-media-retry.test.ts
  • Scenario the test should lock in: explicit Telegram proxy downloads skip target DNS pinning, still enforce hostname allowlists, and propagate the trusted explicit-proxy intent through the media fetch seam.
  • Why this is the smallest reliable guardrail: the bug lives in the shared guarded-fetch/media seam; these tests hit the actual policy handoff without needing a live proxy fixture.
  • Existing test that already covers this (if any): N/A
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • Telegram media downloads work again behind operator-configured explicit HTTP proxies after v2026.4.8.

Diagram (if applicable)

Before:
[Telegram media download] -> [strict guarded fetch] -> [local DNS pin target host] -> [proxy-backed install fails]

After:
[Telegram media download] -> [trusted explicit-proxy guarded fetch] -> [hostname policy check] -> [proxy resolves target DNS] -> [download succeeds]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local Node 22 dev checkout
  • Model/provider: N/A
  • Integration/channel (if any): Telegram
  • Relevant config (redacted): channels.telegram.proxy=http://<proxy-host>:8888

Steps

  1. Configure Telegram with an explicit HTTP proxy.
  2. Trigger a Bot API media download (getFile + file fetch).
  3. Observe the guarded-fetch path used for the download.

Expected

  • The explicit proxy resolves the target hostname after hostname-policy checks, and the download completes.

Actual

  • The old path resolved the target locally before dialing the proxy, which broke proxy-backed installs and surfaced as could not download media.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: targeted serial tests for fetch-guard, media fetch, and Telegram media resolution; full pnpm build.
  • Edge cases checked: explicit proxy on localhost with allowPrivateProxy, off-allowlist target still blocked in trusted explicit-proxy mode.
  • What you did not verify: live Telegram media download against a real proxy endpoint.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: trusted explicit-proxy mode could look like an SSRF widening if it skipped hostname policy too.
    • Mitigation: the new path still enforces hostname allowlists and literal-host blocking before the proxy request, and tests lock that behavior in.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • extensions/telegram/src/bot/delivery.resolve-media-retry.test.ts (modified, +10/-1)
  • extensions/telegram/src/bot/delivery.resolve-media.ts (modified, +9/-0)
  • src/infra/net/fetch-guard.ssrf.test.ts (modified, +69/-0)
  • src/infra/net/fetch-guard.ts (modified, +21/-1)
  • src/infra/net/ssrf.ts (modified, +35/-16)
  • src/media/fetch.test.ts (modified, +34/-0)
  • src/media/fetch.ts (modified, +14/-2)

Code Example

openclaw memory status --deep --agent main
openclaw memory search --agent main --query "test"

---

Error: getaddrinfo ENOTFOUND api.ohmygpt.com

---

# Environment
HTTPS_PROXY=http://127.0.0.1:7890 (Clash TUN with fake-IP mode)

# Embedding config in openclaw agent config
models.providers.openai.baseUrl = "https://api.ohmygpt.com/v1"
memorySearch.remote.model = "text-embedding-3-small"

---

# Failing path (memory embeddings)
$ openclaw memory status --deep --agent main
Embeddings: unavailable
Error: getaddrinfo ENOTFOUND api.ohmygpt.com

# Working path (same machine, same proxy, same endpoint)
# OpenClaw's own OpenAI SDK calls to api.ohmygpt.com/v1 → OK, returns 1536-dim vectors

---

withRemoteHttpResponse(params)          # src/memory/post-json.ts or similar
fetchWithSsrFGuard({ url, init, policy })   # no mode set → defaults to STRICT
resolveGuardedFetchMode(params)            # returns STRICT (no mode field)
resolvePinnedHostnameWithPolicy(hostname)  # does dns.lookup()ENOTFOUND

---

async function withRemoteHttpResponse(params) {
    const useEnvProxy = hasProxyEnvConfigured();
    const request = useEnvProxy ? withTrustedEnvProxyGuardedFetchMode({
        url: params.url,
        init: params.init,
        policy: params.ssrfPolicy,
        auditContext: params.auditContext ?? "memory-remote"
    }) : {
        url: params.url,
        init: params.init,
        policy: params.ssrfPolicy,
        auditContext: params.auditContext ?? "memory-remote"
    };
    const { response, release } = await fetchWithSsrFGuard(request);
    // ...
}
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Summary

withRemoteHttpResponse() in the memory remote embeddings path does not check hasProxyEnvConfigured() before calling fetchWithSsrFGuard(), causing it to default to strict mode which performs local DNS pre-resolution via resolvePinnedHostnameWithPolicy(). In proxy environments (e.g. Clash TUN/fake-IP, corporate proxies), this DNS lookup fails with getaddrinfo ENOTFOUND before the request ever reaches the proxy, even though proxy-routed requests via the OpenAI SDK succeed on the same machine.

Steps to reproduce

  1. Configure an HTTP/HTTPS proxy via environment variables (HTTPS_PROXY, HTTP_PROXY, or ALL_PROXY).
  2. Use a proxy setup where local DNS cannot resolve the embedding provider hostname (e.g. Clash TUN fake-IP mode, or a corporate proxy with DNS-over-proxy).
  3. Configure a remote embedding provider (e.g. api.ohmygpt.com/v1 or any OpenAI-compatible endpoint).
  4. Run:
openclaw memory status --deep --agent main
openclaw memory search --agent main --query "test"
  1. Observe getaddrinfo ENOTFOUND <hostname> and Embeddings: unavailable.

Expected behavior

When environment proxy variables are configured, withRemoteHttpResponse() should use withTrustedEnvProxyGuardedFetchMode() to set the fetch mode to TRUSTED_ENV_PROXY, causing fetchWithSsrFGuard() to skip local DNS pre-resolution and use EnvHttpProxyAgent() directly — the same behavior already implemented for other proxy-aware code paths in the codebase.

Actual behavior

withRemoteHttpResponse() calls fetchWithSsrFGuard() without setting a mode, which defaults to STRICT. In strict mode, fetchWithSsrFGuard() always calls resolvePinnedHostnameWithPolicy()dns.lookup() before making the HTTP request. This local DNS lookup fails in proxy environments where DNS resolution must go through the proxy, producing:

Error: getaddrinfo ENOTFOUND api.ohmygpt.com

Meanwhile, on the same machine in the same shell session, OpenClaw's own OpenAI SDK calls to the same endpoint succeed — confirming the proxy works and the issue is isolated to the memory embeddings code path.

OpenClaw version

2026.3.13 (61d171a)

Operating system

Windows 11 Pro 10.0.22631

Install method

npm global

Model

openai/text-embedding-3-small (remote embedding provider)

Provider / routing chain

openclaw -> env HTTP proxy (Clash TUN) -> remote OpenAI-compatible embedding endpoint

Additional provider/model setup details

# Environment
HTTPS_PROXY=http://127.0.0.1:7890 (Clash TUN with fake-IP mode)

# Embedding config in openclaw agent config
models.providers.openai.baseUrl = "https://api.ohmygpt.com/v1"
memorySearch.remote.model = "text-embedding-3-small"

The same proxy + endpoint combination works when OpenClaw makes regular OpenAI SDK calls (e.g. chat completions), because those paths correctly use proxy-aware fetch. Only the memory embeddings path fails.

Logs, screenshots, and evidence

# Failing path (memory embeddings)
$ openclaw memory status --deep --agent main
Embeddings: unavailable
Error: getaddrinfo ENOTFOUND api.ohmygpt.com

# Working path (same machine, same proxy, same endpoint)
# OpenClaw's own OpenAI SDK calls to api.ohmygpt.com/v1 → OK, returns 1536-dim vectors

Root cause trace in source:

withRemoteHttpResponse(params)          # src/memory/post-json.ts or similar
  → fetchWithSsrFGuard({ url, init, policy })   # no mode set → defaults to STRICT
    → resolveGuardedFetchMode(params)            # returns STRICT (no mode field)
    → resolvePinnedHostnameWithPolicy(hostname)  # does dns.lookup() → ENOTFOUND

The fix already exists in the codebase for other callers. For example, src/memory/embeddings-remote-*.ts in some build outputs already has the corrected pattern. The issue is that withRemoteHttpResponse() was not updated to use it.

Correct pattern (already present in some bundle copies):

async function withRemoteHttpResponse(params) {
    const useEnvProxy = hasProxyEnvConfigured();
    const request = useEnvProxy ? withTrustedEnvProxyGuardedFetchMode({
        url: params.url,
        init: params.init,
        policy: params.ssrfPolicy,
        auditContext: params.auditContext ?? "memory-remote"
    }) : {
        url: params.url,
        init: params.init,
        policy: params.ssrfPolicy,
        auditContext: params.auditContext ?? "memory-remote"
    };
    const { response, release } = await fetchWithSsrFGuard(request);
    // ...
}

Impact and severity

  • Affected: All users running OpenClaw with env proxy configured (HTTP_PROXY/HTTPS_PROXY/ALL_PROXY) in environments where local DNS cannot resolve the embedding provider hostname (Clash TUN fake-IP, corporate forward proxies, WSL with host-side proxy, etc.)
  • Severity: High — completely blocks memory search functionality; Embeddings: unavailable
  • Frequency: 100% reproducible when the proxy + DNS condition is met
  • Consequence: memory_search tool and memory status --deep are non-functional; agents lose access to vector memory search entirely

Additional information

Note on build artifact duplication: withRemoteHttpResponse() is inlined by the bundler (rolldown) into multiple dist chunks. In 2026.3.13, we found 7 copies across different bundles — some already had the proxy fix, others did not. The source-level fix is a single-location change, but all bundle copies need to be consistent after build.

Affected bundles in 2026.3.13 (for reference):

  • reply-Bm8VrLQh.js — gateway agent tool path (missing fix)
  • auth-profiles-DDVivXkv.js — alternate auth bundle (missing fix)
  • discord-CcCLMjHw.js — discord channel path (missing fix)
  • auth-profiles-DRjqKE3G.js — CLI path (had fix)
  • model-selection-*.js — (had fix)
  • plugin-sdk/thread-bindings-*.js — (had fix)

Workaround: Manually patch withRemoteHttpResponse() in the affected dist bundles to add the hasProxyEnvConfigured() check as shown above.

extent analysis

Fix Plan

To fix the issue, we need to update the withRemoteHttpResponse() function to check for proxy environment configuration and set the fetch mode accordingly. Here are the steps:

  • Update the withRemoteHttpResponse() function to include the hasProxyEnvConfigured() check:
async function withRemoteHttpResponse(params) {
    const useEnvProxy = hasProxyEnvConfigured();
    const request = useEnvProxy ? withTrustedEnvProxyGuardedFetchMode({
        url: params.url,
        init: params.init,
        policy: params.ssrfPolicy,
        auditContext: params.auditContext ?? "memory-remote"
    }) : {
        url: params.url,
        init: params.init,
        policy: params.ssrfPolicy,
        auditContext: params.auditContext ?? "memory-remote"
    };
    const { response, release } = await fetchWithSsrFGuard(request);
    // ...
}
  • Ensure that the hasProxyEnvConfigured() function is correctly implemented to check for the presence of proxy environment variables (HTTPS_PROXY, HTTP_PROXY, or ALL_PROXY).
  • Verify that the withTrustedEnvProxyGuardedFetchMode() function is correctly setting the fetch mode to TRUSTED_ENV_PROXY when a proxy is configured.

Verification

To verify that the fix worked, you can:

  • Run the openclaw memory status --deep --agent main and openclaw memory search --agent main --query "test" commands with the proxy environment variables set.
  • Check that the Embeddings: unavailable error is no longer present and that the memory search functionality is working as expected.
  • Verify that the getaddrinfo ENOTFOUND error is no longer occurring.

Extra Tips

  • Make sure to update all instances of the withRemoteHttpResponse() function in the codebase to ensure consistency.
  • Consider adding additional logging or debugging statements to help diagnose any future issues related to proxy configuration.
  • If you are using a bundler like rolldown, ensure that all bundle copies are updated with the fix to avoid inconsistencies.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

When environment proxy variables are configured, withRemoteHttpResponse() should use withTrustedEnvProxyGuardedFetchMode() to set the fetch mode to TRUSTED_ENV_PROXY, causing fetchWithSsrFGuard() to skip local DNS pre-resolution and use EnvHttpProxyAgent() directly — the same behavior already implemented for other proxy-aware code paths in the codebase.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: memory_search remote embeddings fail with ENOTFOUND when env proxy is configured — withRemoteHttpResponse skips TRUSTED_ENV_PROXY mode [7 pull requests, 2 comments, 3 participants]