openclaw - ✅(Solved) Fix STT: Audio transcription provider requests blocked by SSRF guard for private/LAN IPs (regression in v2026.4.7) [2 pull requests, 1 comments, 2 participants]

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…
GitHub stats
openclaw/openclaw#63132Fetched 2026-04-09 07:58:03
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
0
Timeline (top)
cross-referenced ×3commented ×1referenced ×1

Audio transcription (STT) is broken when using a locally-hosted provider (e.g. Parakeet, Whisper) on a private LAN IP. Requests to the transcription endpoint are blocked by the SSRF guard with:

blocked URL fetch (url-fetch) target=http://192.168.30.208:5092/v1/audio/transcriptions reason=Blocked hostname or private/internal/special-use IP address

This is a regression introduced in v2026.4.7. It was not present in v2026.4.5.

Root Cause

There is a trust boundary asymmetry in how provider requests are made:

  • LLM inference providers (e.g. vLLM, Ollama) use resolveProxyFetchFromEnv() ?? globalThis.fetchraw undici with no SSRF guard. Correctly treated as trusted operator-configured infrastructure.
  • QMD embedding/reranking runs as a subprocess, bypassing the gateway fetch entirely.
  • Audio transcription providers go through fetchWithSsrFGuard — the same guarded path used for user/agent-controlled URLs like web_fetch. Private IPs are blocked with no opt-out.

Audio transcription providers are operator-configured infrastructure (same as LLM providers), but the code routes them through the SSRF guard. This is inconsistent and unintentional.

Relevant files: media-understanding-Cym6m0fM.jstranscribeOpenAiCompatibleAudioresolveProviderHttpRequestConfig passes allowPrivateNetwork: false (hardcoded default, no config path to override).

Fix Action

Fix / Workaround

Any self-hosted STT setup using a local/LAN IP is broken on v2026.4.7+. There is currently no user-configurable workaround — the schema rejects network.dangerouslyAllowPrivateNetwork on models.providers.openai, and there is no equivalent opt-in on tools.media.audio.models entries.

PR fix notes

PR #63147: fix: allow private network access for operator-configured provider endpoints

Description (problem / solution / changelog)

Problem

Audio transcription (STT) requests are blocked by the SSRF guard when the provider is configured to a private/LAN IP (e.g. http://192.168.30.208:5092/v1). This creates a trust boundary asymmetry:

  • LLM inference: buildGuardedModelFetchresolveProviderRequestPolicyConfigallowPrivateNetwork (same code path, same bug but less visible)
  • Audio transcription: transcribeOpenAiCompatibleAudioresolveProviderHttpRequestConfigresolveProviderRequestPolicyConfigallowPrivateNetwork: falsefetchWithSsrFGuard blocks private IP

Root cause: resolveProviderRequestPolicyConfig always returned params.allowPrivateNetwork ?? false, hardcoding false when no explicit override was passed. None of the audio transcription call sites pass allowPrivateNetwork, so private-network endpoints were always blocked.

Closes #63132

Fix

resolveProviderRequestPolicyConfig now falls back to policy.usesExplicitProxyLikeEndpoint instead of false:

// Before
allowPrivateNetwork: params.allowPrivateNetwork ?? false,

// After
allowPrivateNetwork: params.allowPrivateNetwork ?? policy.usesExplicitProxyLikeEndpoint,

usesExplicitProxyLikeEndpoint is true for any custom baseUrl that is not a known native OpenAI/Azure endpoint (i.e. any operator-configured provider endpoint). This matches the existing security model: operator-configured endpoints (proxy, TLS, custom base URL) are treated as trusted infrastructure. An explicit allowPrivateNetwork param always wins, so callers can still force either direction.

Testing

Three new tests in provider-request-config.test.ts:

  1. Confirms allowPrivateNetwork: true for a LAN IP custom endpoint (http://192.168.30.208:5092/v1) with usesExplicitProxyLikeEndpoint: true
  2. Confirms allowPrivateNetwork: false is preserved for the default public OpenAI audio endpoint
  3. Confirms an explicit allowPrivateNetwork param overrides the policy-derived default in both directions

All 21 tests in provider-request-config.test.ts pass. Existing openai-compatible-audio.test.ts tests (2/2) also pass.

Affected paths

  • src/agents/provider-request-config.ts — one-line fix
  • src/agents/provider-request-config.test.ts — three new test cases

🤖 Generated with Claude Code

Changed files

  • src/agents/provider-request-config.test.ts (modified, +78/-0)
  • src/agents/provider-request-config.ts (modified, +10/-1)

PR #62549: fix(ollama): accept baseURL alias so remote Ollama hosts are not ignored

Description (problem / solution / changelog)

Summary

  • Add readProviderBaseUrl() helper that accepts both baseUrl (canonical lowercase) and baseURL (OpenAI SDK convention uppercase)
  • Update all Ollama provider code paths to use the helper for consistent URL resolution
  • Add comprehensive test coverage (12 tests) for both spellings, whitespace handling, and edge cases

Problem

Users familiar with the OpenAI SDK convention often write baseURL (uppercase URL) in their openclaw.json:

{
  "models": {
    "providers": {
      "ollama-lan": {
        "baseURL": "http://192.168.1.100:11434"  // ← OpenAI SDK style
      }
    }
  }
}

But OpenClaw's config schema expects baseUrl (lowercase). This caused remote Ollama hosts to be silently ignored, with requests falling back to localhost:11434 and resulting in:

404 {"error":"model 'qwen3.5-32k:latest' not found"}

Solution

Created readProviderBaseUrl() helper that:

  1. Checks baseUrl (canonical spelling) first
  2. Falls back to baseURL (alternate spelling) if not found
  3. Returns trimmed URL string or undefined

Updated all Ollama provider paths:

  • Provider catalog discovery
  • buildOllamaProvider() call
  • createConfiguredOllamaStreamFn() baseUrl resolution
  • ensureOllamaModelPulled() baseUrl lookup
  • hasMeaningfulExplicitOllamaConfig() check

Test Coverage

CategoryTests
Canonical baseUrl6
Alternate baseURL4
Edge cases2
Total12

All tests pass locally.

Issue

Fixes #62533

Related

  • #54754 - Original bug report
  • #57214 - Previous fix attempt (CI failures, unmerged)
  • #61755 - Multi-provider routing fix

Checklist

  • Code follows project style guidelines
  • Tests added and passing
  • CHANGELOG.md updated
  • Commit message follows conventional commits
  • PR title uses fix: prefix
  • Issue linked with Fixes #62533

Changed files

  • extensions/ollama/index.ts (modified, +11/-9)
  • extensions/ollama/src/embedding-provider.ts (modified, +3/-1)
  • extensions/ollama/src/provider-base-url.test.ts (added, +114/-0)
  • extensions/ollama/src/provider-base-url.ts (added, +41/-0)
  • extensions/ollama/src/setup.ts (modified, +3/-1)

Code Example

blocked URL fetch (url-fetch) target=http://192.168.30.208:5092/v1/audio/transcriptions reason=Blocked hostname or private/internal/special-use IP address

---

"tools": {
  "media": {
    "audio": {
      "enabled": true,
      "models": [
        {
          "provider": "openai",
          "model": "parakeet",
          "baseUrl": "http://192.168.30.208:5092/v1"
        }
      ]
    }
  }
}
RAW_BUFFERClick to expand / collapse

Summary

Audio transcription (STT) is broken when using a locally-hosted provider (e.g. Parakeet, Whisper) on a private LAN IP. Requests to the transcription endpoint are blocked by the SSRF guard with:

blocked URL fetch (url-fetch) target=http://192.168.30.208:5092/v1/audio/transcriptions reason=Blocked hostname or private/internal/special-use IP address

This is a regression introduced in v2026.4.7. It was not present in v2026.4.5.

Configuration

"tools": {
  "media": {
    "audio": {
      "enabled": true,
      "models": [
        {
          "provider": "openai",
          "model": "parakeet",
          "baseUrl": "http://192.168.30.208:5092/v1"
        }
      ]
    }
  }
}

Root Cause

There is a trust boundary asymmetry in how provider requests are made:

  • LLM inference providers (e.g. vLLM, Ollama) use resolveProxyFetchFromEnv() ?? globalThis.fetchraw undici with no SSRF guard. Correctly treated as trusted operator-configured infrastructure.
  • QMD embedding/reranking runs as a subprocess, bypassing the gateway fetch entirely.
  • Audio transcription providers go through fetchWithSsrFGuard — the same guarded path used for user/agent-controlled URLs like web_fetch. Private IPs are blocked with no opt-out.

Audio transcription providers are operator-configured infrastructure (same as LLM providers), but the code routes them through the SSRF guard. This is inconsistent and unintentional.

Relevant files: media-understanding-Cym6m0fM.jstranscribeOpenAiCompatibleAudioresolveProviderHttpRequestConfig passes allowPrivateNetwork: false (hardcoded default, no config path to override).

Impact

Any self-hosted STT setup using a local/LAN IP is broken on v2026.4.7+. There is currently no user-configurable workaround — the schema rejects network.dangerouslyAllowPrivateNetwork on models.providers.openai, and there is no equivalent opt-in on tools.media.audio.models entries.

Expected Behavior

Audio transcription provider requests should be treated as trusted operator-configured infrastructure, consistent with LLM provider calls — either by using unguarded fetch, or by providing a network.dangerouslyAllowPrivateNetwork opt-in on audio model entries (similar to what channel configs support).

Related

  • Fixes for the allowlist/plugin side of STT: #62205, #62234
  • Self-hosted Parakeet STT at http://192.168.30.208:5092/v1

extent analysis

TL;DR

The most likely fix is to update the resolveProviderHttpRequestConfig function to allow private network access for audio transcription providers by setting allowPrivateNetwork to true or providing a configurable opt-in.

Guidance

  • Identify the resolveProviderHttpRequestConfig function in media-understanding-Cym6m0fM.js and update the allowPrivateNetwork parameter to true to bypass the SSRF guard for audio transcription providers.
  • Consider adding a configurable opt-in, such as network.dangerouslyAllowPrivateNetwork, to tools.media.audio.models entries to provide a user-configurable workaround.
  • Review the transcribeOpenAiCompatibleAudio function to ensure it correctly handles the updated allowPrivateNetwork configuration.
  • Test the updated configuration with a self-hosted STT setup using a local/LAN IP to verify the fix.

Example

"tools": {
  "media": {
    "audio": {
      "enabled": true,
      "models": [
        {
          "provider": "openai",
          "model": "parakeet",
          "baseUrl": "http://192.168.30.208:5092/v1",
          "network": {
            "dangerouslyAllowPrivateNetwork": true
          }
        }
      ]
    }
  }
}

Notes

The current implementation treats audio transcription providers as untrusted, which is inconsistent with LLM providers. Updating the allowPrivateNetwork configuration or providing a configurable opt-in should resolve the issue.

Recommendation

Apply a workaround by updating the resolveProviderHttpRequestConfig function to allow private network access for audio transcription providers, as this is a regression introduced in v2026.4.7 and a proper fix may require further changes to the underlying architecture.

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