openclaw - 💡(How to fix) Fix [Bug]: [REGRESSION] [Fix] 2026.5.12 SSRF protection blocks private/CGNAT model provider endpoints by default, breaking self-hosted LMStudio/vLLM/Ollama setups

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

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…

The 2026.5.12 release introduced default-on SSRF protection for model provider fetch requests. This blocks connections to any endpoint resolving to private, CGNAT, or internal IP ranges — including Tailscale CGNAT addresses (100.64.0.0/10) commonly used for self-hosted providers like LMStudio, vLLM, and Ollama. The result is a hard break for any self-hosted setup behind Tailscale, WireGuard, or LAN IPs, with no migration path or warning documented.

Error Message

Log Evidence SSRF Block (repeating every agent run)

warn security {"subsystem":"security"} blocked URL fetch (url-fetch) targetOrigin=http://100.77.77.111:8877/ reason=Blocked hostname or private/internal/special-use IP address warn provider-transport-fetch {"subsystem":"provider-transport-fetch"} [model-fetch] error provider=lmstudio api=openai-completions model=qwen/qwen3.6-35b-a3b elapsedMs=2 name=SsrFBlockedError code=undefined causeName=undefined causeCode=undefined message=Blocked hostname or private/internal/special-use IP address text

Cascading Agent Failure

warn agent/embedded {"subsystem":"agent/embedded"} {"event":"embedded_run_agent_end","tags":["error_handling","lifecycle","agent_end","assistant_error"],"isError":true,"error":"LLM request failed: network connection error.","failoverReason":"timeout","providerRuntimeFailureKind":"timeout"} warn model-fallback/decision {"subsystem":"model-fallback/decision"} {"decision":"candidate_failed","fallbackStepFinalOutcome":"chain_exhausted","reason":"timeout"} error diagnostic {"subsystem":"diagnostic"} lane task error: error="FailoverError: LLM request failed: network connection error." error Embedded agent failed before reply: LLM request failed: network connection error. text

Cron Job Failure + Backoff

warn cron {"module":"cron"} {"jobId":"67aecddf-...","jobName":"HOURLY LOGS","error":"FailoverError: LLM request failed: network connection error."} cron: job run returned error status info cron {"module":"cron"} {"consecutiveErrors":3,"backoffMs":300000} cron: applying error backoff text

Broken Config Keys Attempted

The 2026.5.12 config schema rejects every intuitive key a user might try to bypass this. Here is the full list of attempts and their validation errors:

Attempted KeyError
<root>.dangerousAllowPrivateUrlsConfig validation failed: <root>: Unrecognized key: "dangerousAllowPrivateUrls"
gateway.dangerousAllowPrivateUrlsConfig validation failed: gateway: Unrecognized key: "dangerousAllowPrivateUrls"
<root>.securityConfig validation failed: <root>: Unrecognized key: "security"
gateway.securityConfig validation failed: gateway: Unrecognized key: "security"
<root>.fetchConfig validation failed: <root>: Unrecognized key: "fetch"
gateway.fetchConfig validation failed: gateway: Unrecognized key: "fetch"
gateway.ssrfConfig validation failed: gateway: Unrecognized key: "ssrf"
gateway.providersConfig validation failed: gateway: Unrecognized key: "providers"
<root>.providersConfig validation failed: <root>: Unrecognized key: "providers"

None of these are documented anywhere. The only way to find the correct key is to dump the schema (openclaw config schema) and grep for SSRF-related fields.

Working Fix

The correct per-provider config key, found only by dumping the schema:

openclaw config set models.providers.lmstudio.request.allowPrivateNetwork true openclaw gateway restart

The schema description for this field reads:

"When true, allow HTTPS to the model base URL when DNS resolves to private, CGNAT, or similar ranges, via the provider HTTP fetch guard (fetchWithSsrFGuard). OpenAI Responses WebSocket reuses request for headers/TLS but does not use that fetch SSRF path. Use only for operator-controlled self-hosted OpenAI-compatible endpoints (LAN, overlay, split DNS). Default is false."

Verification

After applying the fix, logs show:

 ✅ Zero SsrFBlockedError messages
 ✅ Zero FailoverError messages
 ✅ Successful model completions: info channels/slack delivered reply to channel:C0B254QFYNN
 ✅ Gateway hot-reload picked up the change: info gateway/reload config hot reload applied (models.providers.lmstudio.request)

Root Cause

The entire OpenClaw setup is bricked. All agent runs (primary and fallbacks), cron jobs, Slack channel interactions, and webchat fail immediately. Because the SSRF guard blocks the request at the network level before it reaches the provider transport, no model fallback can succeed. Any self-hosted deployment using Tailscale, WireGuard, or LAN IPs is completely dead in the water with no incoming or outgoing AI functionality.

Fix Action

Fix / Workaround

  1. Configure a provider pointing to a private/CGNAT IP (e.g. http://100.77.77.111:8877/v1 over Tailscale)
  2. Verify it works on 2026.5.11 or earlier
  3. Upgrade to 2026.5.12
  4. Trigger any agent run (Slack message, webchat, cron)
  5. Agent fails with FailoverError: LLM request failed: network connection error.
  6. Logs show SsrFBlockedError: Blocked hostname or private/internal/special-use IP address

Code Example

Log Evidence
SSRF Block (repeating every agent run)

warn security {"subsystem":"security"} blocked URL fetch (url-fetch) targetOrigin=http://100.77.77.111:8877/ reason=Blocked hostname or private/internal/special-use IP address
warn provider-transport-fetch {"subsystem":"provider-transport-fetch"} [model-fetch] error provider=lmstudio api=openai-completions model=qwen/qwen3.6-35b-a3b elapsedMs=2 name=SsrFBlockedError code=undefined causeName=undefined causeCode=undefined message=Blocked hostname or private/internal/special-use IP address
text

### Cascading Agent Failure
 
warn agent/embedded {"subsystem":"agent/embedded"} {"event":"embedded_run_agent_end","tags":["error_handling","lifecycle","agent_end","assistant_error"],"isError":true,"error":"LLM request failed: network connection error.","failoverReason":"timeout","providerRuntimeFailureKind":"timeout"}
warn model-fallback/decision {"subsystem":"model-fallback/decision"} {"decision":"candidate_failed","fallbackStepFinalOutcome":"chain_exhausted","reason":"timeout"}
error diagnostic {"subsystem":"diagnostic"} lane task error: error="FailoverError: LLM request failed: network connection error."
error Embedded agent failed before reply: LLM request failed: network connection error.
text
 
  
 
 

### Cron Job Failure + Backoff

warn cron {"module":"cron"} {"jobId":"67aecddf-...","jobName":"HOURLY LOGS","error":"FailoverError: LLM request failed: network connection error."} cron: job run returned error status
info cron {"module":"cron"} {"consecutiveErrors":3,"backoffMs":300000} cron: applying error backoff
text
 
## Broken Config Keys Attempted

The 2026.5.12 config schema rejects every intuitive key a user might try to bypass this. Here is the full list of attempts and their validation errors:

| Attempted Key | Error |
|---|---|
| `<root>.dangerousAllowPrivateUrls` | `Config validation failed: <root>: Unrecognized key: "dangerousAllowPrivateUrls"` |
| `gateway.dangerousAllowPrivateUrls` | `Config validation failed: gateway: Unrecognized key: "dangerousAllowPrivateUrls"` |
| `<root>.security` | `Config validation failed: <root>: Unrecognized key: "security"` |
| `gateway.security` | `Config validation failed: gateway: Unrecognized key: "security"` |
| `<root>.fetch` | `Config validation failed: <root>: Unrecognized key: "fetch"` |
| `gateway.fetch` | `Config validation failed: gateway: Unrecognized key: "fetch"` |
| `gateway.ssrf` | `Config validation failed: gateway: Unrecognized key: "ssrf"` |
| `gateway.providers` | `Config validation failed: gateway: Unrecognized key: "providers"` |
| `<root>.providers` | `Config validation failed: <root>: Unrecognized key: "providers"` |

None of these are documented anywhere. The only way to find the correct key is to dump the schema (`openclaw config schema`) and grep for SSRF-related fields.

## Working Fix

The correct per-provider config key, found only by dumping the schema:


openclaw config set models.providers.lmstudio.request.allowPrivateNetwork true
openclaw gateway restart

The schema description for this field reads:

    "When true, allow HTTPS to the model base URL when DNS resolves to private, CGNAT, or similar ranges, via the provider HTTP fetch guard (fetchWithSsrFGuard). OpenAI Responses WebSocket reuses request for headers/TLS but does not use that fetch SSRF path. Use only for operator-controlled self-hosted OpenAI-compatible endpoints (LAN, overlay, split DNS). Default is false."

Verification

After applying the fix, logs show:

Zero SsrFBlockedError messages
Zero FailoverError messages
Successful model completions: info channels/slack delivered reply to channel:C0B254QFYNN
Gateway hot-reload picked up the change: info gateway/reload config hot reload applied (models.providers.lmstudio.request)

---

openclaw config set models.providers.lmstudio.request.allowPrivateNetwork true
openclaw gateway restart
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

The 2026.5.12 release introduced default-on SSRF protection for model provider fetch requests. This blocks connections to any endpoint resolving to private, CGNAT, or internal IP ranges — including Tailscale CGNAT addresses (100.64.0.0/10) commonly used for self-hosted providers like LMStudio, vLLM, and Ollama. The result is a hard break for any self-hosted setup behind Tailscale, WireGuard, or LAN IPs, with no migration path or warning documented.

Steps to reproduce

Steps to Reproduce

  1. Configure a provider pointing to a private/CGNAT IP (e.g. http://100.77.77.111:8877/v1 over Tailscale)
  2. Verify it works on 2026.5.11 or earlier
  3. Upgrade to 2026.5.12
  4. Trigger any agent run (Slack message, webchat, cron)
  5. Agent fails with FailoverError: LLM request failed: network connection error.
  6. Logs show SsrFBlockedError: Blocked hostname or private/internal/special-use IP address

Expected behavior

Expected Behavior

  • Existing provider configs using private IPs should either work on upgrade or trigger a prominent startup warning with the exact fix command.
  • Agent errors should identify SSRF as the cause, not report a generic "network connection error" / "timeout".
  • Schema validation should suggest the correct key when intuitive keys like gateway.ssrf are rejected.
  • The request.allowPrivateNetwork key should be documented in the 2026.5.12 upgrade notes and provider docs.

Actual behavior

Actual Behavior

  • Gateway starts "healthy" with zero warnings about SSRF blocking existing providers.
  • Agent runs fail with misleading network connection error / timeout.
  • The actual cause (SsrFBlockedError) is buried at warn level in subsystem logs.
  • Schema validation rejects all intuitive bypass keys (e.g., gateway.ssrf, gateway.fetch) with no hint toward the correct one.
  • The actual bypass key (models.providers.<name>.request.allowPrivateNetwork) is undocumented and only discoverable by dumping and grepping the raw schema.

OpenClaw version

2026.5.12

Operating system

Win11 WSL2 Ubuntu 24

Install method

No response

Model

qwen/qwen3.6-35b-a3b

Provider / routing chain

Slack -> Openclaw -> Tailscale -> LM Studio -> Qwen

Additional provider/model setup details

Additional Provider/Model Setup Details

  • Provider: lmstudio
  • Base URL: http://100.77.77.111:8877/v1 (Tailscale CGNAT IP 100.64.0.0/10)
  • API format: openai-completions
  • Model ID: qwen/qwen3.6-35b-a3b
  • Embedding model: text-embedding-nomic-embed-text-v1.5 (same endpoint)
  • Config path: models.providers.lmstudio

Logs, screenshots, and evidence

Log Evidence
SSRF Block (repeating every agent run)

warn security {"subsystem":"security"} blocked URL fetch (url-fetch) targetOrigin=http://100.77.77.111:8877/ reason=Blocked hostname or private/internal/special-use IP address
warn provider-transport-fetch {"subsystem":"provider-transport-fetch"} [model-fetch] error provider=lmstudio api=openai-completions model=qwen/qwen3.6-35b-a3b elapsedMs=2 name=SsrFBlockedError code=undefined causeName=undefined causeCode=undefined message=Blocked hostname or private/internal/special-use IP address
text

### Cascading Agent Failure
 
warn agent/embedded {"subsystem":"agent/embedded"} {"event":"embedded_run_agent_end","tags":["error_handling","lifecycle","agent_end","assistant_error"],"isError":true,"error":"LLM request failed: network connection error.","failoverReason":"timeout","providerRuntimeFailureKind":"timeout"}
warn model-fallback/decision {"subsystem":"model-fallback/decision"} {"decision":"candidate_failed","fallbackStepFinalOutcome":"chain_exhausted","reason":"timeout"}
error diagnostic {"subsystem":"diagnostic"} lane task error: error="FailoverError: LLM request failed: network connection error."
error Embedded agent failed before reply: LLM request failed: network connection error.
text
 
  
 
 

### Cron Job Failure + Backoff

warn cron {"module":"cron"} {"jobId":"67aecddf-...","jobName":"HOURLY LOGS","error":"FailoverError: LLM request failed: network connection error."} cron: job run returned error status
info cron {"module":"cron"} {"consecutiveErrors":3,"backoffMs":300000} cron: applying error backoff
text
 
## Broken Config Keys Attempted

The 2026.5.12 config schema rejects every intuitive key a user might try to bypass this. Here is the full list of attempts and their validation errors:

| Attempted Key | Error |
|---|---|
| `<root>.dangerousAllowPrivateUrls` | `Config validation failed: <root>: Unrecognized key: "dangerousAllowPrivateUrls"` |
| `gateway.dangerousAllowPrivateUrls` | `Config validation failed: gateway: Unrecognized key: "dangerousAllowPrivateUrls"` |
| `<root>.security` | `Config validation failed: <root>: Unrecognized key: "security"` |
| `gateway.security` | `Config validation failed: gateway: Unrecognized key: "security"` |
| `<root>.fetch` | `Config validation failed: <root>: Unrecognized key: "fetch"` |
| `gateway.fetch` | `Config validation failed: gateway: Unrecognized key: "fetch"` |
| `gateway.ssrf` | `Config validation failed: gateway: Unrecognized key: "ssrf"` |
| `gateway.providers` | `Config validation failed: gateway: Unrecognized key: "providers"` |
| `<root>.providers` | `Config validation failed: <root>: Unrecognized key: "providers"` |

None of these are documented anywhere. The only way to find the correct key is to dump the schema (`openclaw config schema`) and grep for SSRF-related fields.

## Working Fix

The correct per-provider config key, found only by dumping the schema:


openclaw config set models.providers.lmstudio.request.allowPrivateNetwork true
openclaw gateway restart

The schema description for this field reads:

    "When true, allow HTTPS to the model base URL when DNS resolves to private, CGNAT, or similar ranges, via the provider HTTP fetch guard (fetchWithSsrFGuard). OpenAI Responses WebSocket reuses request for headers/TLS but does not use that fetch SSRF path. Use only for operator-controlled self-hosted OpenAI-compatible endpoints (LAN, overlay, split DNS). Default is false."

Verification

After applying the fix, logs show:

     ✅ Zero SsrFBlockedError messages
     ✅ Zero FailoverError messages
     ✅ Successful model completions: info channels/slack delivered reply to channel:C0B254QFYNN
     ✅ Gateway hot-reload picked up the change: info gateway/reload config hot reload applied (models.providers.lmstudio.request)

Impact and severity

Impact and Severity

Severity: Critical — Total Outage

The entire OpenClaw setup is bricked. All agent runs (primary and fallbacks), cron jobs, Slack channel interactions, and webchat fail immediately. Because the SSRF guard blocks the request at the network level before it reaches the provider transport, no model fallback can succeed. Any self-hosted deployment using Tailscale, WireGuard, or LAN IPs is completely dead in the water with no incoming or outgoing AI functionality.

Additional information

Additional Info

🔴 Working Fix: The correct per-provider config key (undocumented, found only by dumping the schema):

openclaw config set models.providers.lmstudio.request.allowPrivateNetwork true
openclaw gateway restart

🔴 Discovery: The correct key path was found by running openclaw config schema | grep -i -A2 "private\|ssrf". Every intuitive key attempted (e.g. gateway.ssrf, gateway.fetch, <root>.security) was rejected by schema validation with zero hints pointing to the actual location.

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…

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 - 💡(How to fix) Fix [Bug]: [REGRESSION] [Fix] 2026.5.12 SSRF protection blocks private/CGNAT model provider endpoints by default, breaking self-hosted LMStudio/vLLM/Ollama setups