Voice mode fails with 'Voice connection failed' — Cloudflare challenge blocks WebSocket to claude.ai

Status Fixed / completed
Reported on v2.1.76
Maintainer reply ✓ Yes — ashwin-ant
Activity 6 comments · opened Mar 14, 2026 · closed Apr 18, 2026
💡 Likely answer: A maintainer (ashwin-ant, collaborator) responded on this thread — see the highlighted reply below.

Environment

  • OS: Windows 10/11 (x64)
  • Node.js: v20.18.1
  • Claude Code: 2.1.76
  • Auth: claude.ai OAuth, subscription: max
  • Region: Romania (Bucharest), ISP: DIGI ROMANIA S.A. (AS8708)

Bug Description

/voice enables successfully ("Voice mode enabled. Hold Space to record."), but after recording and releasing Space, it always fails with:

Voice connection failed. Check your network and try again.

Root Cause Analysis

The voice stream WebSocket (wss://claude.ai/api/ws/speech_to_text/voice_stream) never connects because Cloudflare blocks all programmatic requests to claude.ai from this IP/region with a JavaScript challenge.

Any HTTP request to claude.ai returns:

HTTP 403
cf-mitigated: challenge
server: cloudflare

This challenge cannot be solved by a CLI/Node.js WebSocket client, so the connection never establishes. The finishRecording() function sees wsConnected=false and transcriptChars=0, triggering the "Voice connection failed" error.

What Works

| Component | Status |
|-----------|--------|
| Native audio module (audio-capture.node x64-win32) | Loads OK, 7 exports |
| OAuth authentication | loggedIn: true |
| api.anthropic.com (main API) | Works fine (no Cloudflare challenge) |
| Microphone / audio devices | 4 devices, all status OK |
| Windows Firewall | Claude rules: Allow in/out |
| DNS resolution for claude.ai | Resolves to 160.79.104.10 |
| TLS to claude.ai | TLSv1.3, certificate valid |

What Fails

  • ANY programmatic request from Node.js to claude.ai → 403 with cf-mitigated: challenge
  • WebSocket upgrade to wss://claude.ai/... → blocked by Cloudflare before reaching server

Reproduction

# This returns 403 with cf-mitigated: challenge
curl -s -o /dev/null -w "%{http_code}" https://claude.ai
# Returns: 403

# This works fine
curl -s -o /dev/null -w "%{http_code}" https://api.anthropic.com
# Returns: 404 (expected, no auth)

Expected Behavior

Voice WebSocket should connect to claude.ai without being blocked by Cloudflare challenge, similar to how api.anthropic.com handles CLI connections.

Workaround

Using a VPN changes the IP and bypasses the Cloudflare challenge, making voice mode work. This confirms the issue is IP/region-based Cloudflare challenge policy.

Suggested Fix

Consider one of:

  1. Exempting the /api/ws/speech_to_text/voice_stream endpoint from Cloudflare JavaScript challenges (requests include valid OAuth Bearer tokens)
  2. Using a separate non-challenge-protected domain for the voice stream (similar to api.anthropic.com)
  3. Adding a Cloudflare bypass token/header for authenticated CLI clients

View original on GitHub ↗

6 Comments

github-actions[bot] · 5 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/34094
  2. https://github.com/anthropics/claude-code/issues/33421
  3. https://github.com/anthropics/claude-code/issues/33383

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

Dany-Axhor · 5 months ago

Additional confirmation — Windows 11, native binary, VPN tested

Environment:

  • OS: Windows 11 Pro (22631)
  • Claude Code: 2.1.76 (native binary install via claude.exe, NOT npm)
  • Auth: claude.ai OAuth, subscription: Max x20
  • Region: France

Same symptoms: Recording indicator appears, push-to-talk works, but no transcription on release — silent failure (no error message displayed, unlike the OP who gets "Voice connection failed").

Additional finding — VPN does NOT help:

Tested with ExpressVPN (US Houston, TX). The Cloudflare challenge persists because it's triggered by the User-Agent (Node.js/WebSocket), not the IP address:

# With VPN (US Houston) — still 403:
curl -sI https://claude.ai → HTTP/1.1 403 Forbidden, cf-mitigated: challenge

# Same request with browser User-Agent — works:
curl -sI -H "User-Agent: Mozilla/5.0 ..." https://claude.ai → HTTP/1.1 302 Found

This confirms the Cloudflare challenge is UA-based, not IP/region-based. A VPN is not a viable workaround.

Workaround: Using VoiceMode MCP with local Whisper STT instead of native /voice.

moll · 5 months ago

Seeing the same thing from a Thailand local ISP's fiberoptic connection here — Curling https://claude.ai being blocked with 403 and the voice mode itself failing with "Check your connection". Rest of Claude Code seems to work fine fortunately except voice mode.

infinitewatts · 5 months ago

The issue is people are letting go of the spacebar instead of holding it.

ashwin-ant collaborator · 4 months ago

This was fixed in v2.1.80 — Voice mode now connects via api.anthropic.com instead of claude.ai, avoiding Cloudflare bot-challenge failures on the WebSocket. If you're still seeing this in the latest version, please comment with your version and repro and we'll reopen.

github-actions[bot] · 4 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.