Summary
openclaw memory search (and gateway-side memory_search) fails with fetch failed on servers that require HTTP proxy for outbound HTTPS access. The Gemini embedding API call in the memory manager does not pass proxy: "env" to fetchWithSsrFGuard, so the request bypasses the configured proxy and gets blocked by firewall rules.
Environment
- OpenClaw v2026.2.26 (npm global install)
- Ubuntu 22.04 on DigitalOcean
- Node.js v22.22.0
- iptables blocks direct outbound HTTPS for the service user
- tinyproxy on
127.0.0.1:8888 with allowlist (including generativelanguage.googleapis.com)
HTTPS_PROXY=http://127.0.0.1:8888 set in both shell and systemd unit
Steps to Reproduce
- Set up a server where the gateway user can only reach the internet through an HTTP proxy
- Set
HTTPS_PROXY and HTTP_PROXY env vars
- Configure memory search with Gemini embeddings (default provider)
- Run
openclaw memory search --agent <id> "test query"
Expected: Request goes through the proxy, embedding succeeds
Actual: Memory search failed: fetch failed (ECONNREFUSED — direct connection attempted)
Root Cause
In the built dist files (dist/plugin-sdk/manager-*.js and dist/manager-*.js), the withRemoteHttpResponse function calls fetchWithSsrFGuard without proxy: "env":
async function withRemoteHttpResponse(params) {
const { response, release } = await fetchWithSsrFGuard({
url: params.url,
init: params.init,
policy: params.ssrfPolicy,
auditContext: params.auditContext ?? "memory-remote"
// ← missing: proxy: "env"
});
The fetchWithSsrFGuard function in fetch-guard-*.js only creates an EnvHttpProxyAgent when params.proxy === "env" is explicitly passed:
if (params.proxy === "env" && hasEnvProxyConfigured())
dispatcher = new EnvHttpProxyAgent();
Other code paths (e.g., Telegram channel, web_fetch tool) already pass proxy: "env" correctly.
Workaround
Patch all manager files to add proxy: "env":
for f in /usr/lib/node_modules/openclaw/dist/manager-*.js \
/usr/lib/node_modules/openclaw/dist/plugin-sdk/manager-*.js; do
sed -i 's/auditContext: params.auditContext ?? "memory-remote"/auditContext: params.auditContext ?? "memory-remote",\n\t\tproxy: "env"/' "$f"
done
Must be re-applied after every update.
Proposed Fix
In src/memory/embeddings-*.ts (or wherever withRemoteHttpResponse is defined), add proxy: "env" to the fetchWithSsrFGuard call:
const { response, release } = await fetchWithSsrFGuard({
url: params.url,
init: params.init,
policy: params.ssrfPolicy,
auditContext: params.auditContext ?? "memory-remote",
proxy: "env", // <-- add this
});
Related
Summary
openclaw memory search(and gateway-side memory_search) fails withfetch failedon servers that require HTTP proxy for outbound HTTPS access. The Gemini embedding API call in the memory manager does not passproxy: "env"tofetchWithSsrFGuard, so the request bypasses the configured proxy and gets blocked by firewall rules.Environment
127.0.0.1:8888with allowlist (includinggenerativelanguage.googleapis.com)HTTPS_PROXY=http://127.0.0.1:8888set in both shell and systemd unitSteps to Reproduce
HTTPS_PROXYandHTTP_PROXYenv varsopenclaw memory search --agent <id> "test query"Expected: Request goes through the proxy, embedding succeeds
Actual:
Memory search failed: fetch failed(ECONNREFUSED — direct connection attempted)Root Cause
In the built dist files (
dist/plugin-sdk/manager-*.jsanddist/manager-*.js), thewithRemoteHttpResponsefunction callsfetchWithSsrFGuardwithoutproxy: "env":The
fetchWithSsrFGuardfunction infetch-guard-*.jsonly creates anEnvHttpProxyAgentwhenparams.proxy === "env"is explicitly passed:Other code paths (e.g., Telegram channel, web_fetch tool) already pass
proxy: "env"correctly.Workaround
Patch all manager files to add
proxy: "env":Must be re-applied after every update.
Proposed Fix
In
src/memory/embeddings-*.ts(or whereverwithRemoteHttpResponseis defined), addproxy: "env"to thefetchWithSsrFGuardcall:Related
web_fetchnot passing ssrfPolicy through fetchWithSsrFGuard