hermes - 💡(How to fix) Fix Custom providers behind Cloudflare WAF return 403 due to SDK User-Agent

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…

Error Message

PermissionDeniedError: HTTP 403: Your request was blocked.

Root Cause

The Anthropic SDK (anthropic Python package) and OpenAI SDK both send identifying User-Agent headers by default:

  • Anthropic/Python 0.101.0
  • OpenAI/Python 2.36.0

Cloudflare's bot detection rules block these User-Agent patterns. This was verified by testing the same endpoint with and without the SDK User-Agent:

# Without SDK User-Agent → 200 OK
curl -X POST https://proxy.example.com/v1/messages \
  -H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" \
  -d '{"model":"...","max_tokens":10,"messages":[{"role":"user","content":"hi"}]}'

# With SDK User-Agent → 403 Forbidden
curl -X POST https://proxy.example.com/v1/messages \
  -H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" \
  -H "User-Agent: Anthropic/Python 0.101.0" \
  -d '{"model":"...","max_tokens":10,"messages":[{"role":"user","content":"hi"}]}'

In the codebase, build_anthropic_client() in agent/anthropic_adapter.py does not set a custom User-Agent for third-party endpoints (the _is_third_party_anthropic_endpoint branch). Similarly, the OpenAI client construction in run_agent.py does not override the SDK User-Agent for custom providers.

Fix Action

Workaround

Patching build_anthropic_client() to set User-Agent: hermes-agent in the third-party endpoint branch works, but is not configurable and gets overwritten on update.

Code Example

PermissionDeniedError: HTTP 403: Your request was blocked.

---

# Without SDK User-Agent200 OK
curl -X POST https://proxy.example.com/v1/messages \
  -H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" \
  -d '{"model":"...","max_tokens":10,"messages":[{"role":"user","content":"hi"}]}'

# With SDK User-Agent403 Forbidden
curl -X POST https://proxy.example.com/v1/messages \
  -H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" \
  -H "User-Agent: Anthropic/Python 0.101.0" \
  -d '{"model":"...","max_tokens":10,"messages":[{"role":"user","content":"hi"}]}'

---

custom_providers:
- name: my-proxy
  base_url: https://proxy.example.com
  api_key: sk-xxx
  api_mode: anthropic_messages
  user_agent: my-custom-agent  # optional, defaults to 'hermes-agent'
RAW_BUFFERClick to expand / collapse

Problem

When using custom_providers with third-party API proxies (e.g. self-hosted relays, GLM proxies and so on) that sit behind Cloudflare or similar WAFs, all API requests fail with HTTP 403:

PermissionDeniedError: HTTP 403: Your request was blocked.

Root Cause

The Anthropic SDK (anthropic Python package) and OpenAI SDK both send identifying User-Agent headers by default:

  • Anthropic/Python 0.101.0
  • OpenAI/Python 2.36.0

Cloudflare's bot detection rules block these User-Agent patterns. This was verified by testing the same endpoint with and without the SDK User-Agent:

# Without SDK User-Agent → 200 OK
curl -X POST https://proxy.example.com/v1/messages \
  -H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" \
  -d '{"model":"...","max_tokens":10,"messages":[{"role":"user","content":"hi"}]}'

# With SDK User-Agent → 403 Forbidden
curl -X POST https://proxy.example.com/v1/messages \
  -H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" \
  -H "User-Agent: Anthropic/Python 0.101.0" \
  -d '{"model":"...","max_tokens":10,"messages":[{"role":"user","content":"hi"}]}'

In the codebase, build_anthropic_client() in agent/anthropic_adapter.py does not set a custom User-Agent for third-party endpoints (the _is_third_party_anthropic_endpoint branch). Similarly, the OpenAI client construction in run_agent.py does not override the SDK User-Agent for custom providers.

Proposed Solution

Add an optional user_agent field to custom_providers configuration:

custom_providers:
- name: my-proxy
  base_url: https://proxy.example.com
  api_key: sk-xxx
  api_mode: anthropic_messages
  user_agent: my-custom-agent  # optional, defaults to 'hermes-agent'

When user_agent is set (or defaults to 'hermes-agent'), it overrides the SDK's default User-Agent for that custom provider's API calls.

Workaround

Patching build_anthropic_client() to set User-Agent: hermes-agent in the third-party endpoint branch works, but is not configurable and gets overwritten on update.

Environment

  • Hermes Agent v0.13.0
  • Python 3.13.5
  • anthropic SDK 0.101.0
  • openai SDK 2.36.0
  • Provider: third-party proxy behind Cloudflare

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

hermes - 💡(How to fix) Fix Custom providers behind Cloudflare WAF return 403 due to SDK User-Agent