[Bug] Voice mode WebSocket connection blocked by Cloudflare challenge on claude.ai

Resolved 💬 3 comments Opened Mar 4, 2026 by IgorKey Closed Mar 8, 2026

Bug Description
Voice mode fails with error: "Voice stream error: Connection closed: code 1002 — Expected 101 status code"

Root cause: Cloudflare managed challenge on claude.ai blocks the direct WebSocket connection from Claude Code CLI.

When Claude Code tries to connect to wss://claude.ai/api/ws/speech_to_text/voice_stream,
Cloudflare returns HTTP 403 instead of 101 (WebSocket upgrade), because the CLI client
cannot pass the Cloudflare JS challenge and doesn't have a cf_clearance cookie.

Voice works perfectly fine in the claude.ai web app — the browser passes the Cloudflare
challenge, gets the cf_clearance cookie, and the WebSocket upgrade succeeds.

Environment:

  • Claude Code version: 2.1.66 (Homebrew cask, macOS)
  • Subscription: Max
  • Auth: OAuth (logged in via claude login)
  • Network: EU (Germany) IP, no VPN, no corporate proxy
  • curl https://claude.ai returns 403 with cf-mitigated: challenge

Steps to reproduce:

  1. /voice to enable voice mode
  2. Hold Space to record
  3. Error appears immediately: "Voice stream error: Connection closed: code 1002"

Expected: WebSocket connects to claude.ai speech_to_text endpoint successfully
Actual: Cloudflare blocks the connection with 403 (managed challenge)

Environment Info

  • Platform: darwin
  • Terminal: intellij
  • Version: 2.1.66
  • Feedback ID: bef172ff-03ff-46d1-84e0-c57a2461ea4e

Errors

[{"error":"Error: 1P event logging: 67 events failed to export (status=429, code=ERR_BAD_REQUEST, Request failed with status code 429)\n    at queueFailedEvents (/$bunfs/root/claude:6264:2654)\n    at async doExport (/$bunfs/root/claude:6264:1561)\n    at processTicksAndRejections (native:7:39)","timestamp":"2026-03-04T08:32:15.508Z"},{"error":"Error: {\"message\":\"Failed to export 67 events (status=429, code=ERR_BAD_REQUEST, Request failed with status code 429)\",\"originalLine\":\"6264\",\"originalColumn\":\"1713\",\"line\":\"6264\",\"column\":\"1713\",\"sourceURL\":\"/$bunfs/root/claude\",\"stack\":\"Error: Failed to export 67 events (status=429, code=ERR_BAD_REQUEST, Request failed with status code 429)\\n    at doExport (/$bunfs/root/claude:6264:1713)\\n    at processTicksAndRejections (native:7:39)\",\"name\":\"Error\"}\n    at error (/$bunfs/root/claude:2402:25029)\n    at <anonymous> (/$bunfs/root/claude:119:92465)\n    at A4D (/$bunfs/root/claude:119:93009)\n    at <anonymous> (/$bunfs/root/claude:120:17366)\n    at processTicksAndRejections (native:7:39)","timestamp":"2026-03-04T08:32:15.508Z"},{"error":"Error: 1P event logging: 4 events failed to export (status=429, code=ERR_BAD_REQUEST, Request failed with status code 429)\n    at queueFailedEvents (/$bunfs/root/claude:6264:2654)\n    at async doExport (/$bunfs/root/claude:6264:1561)\n    at processTicksAndRejections (native:7:39)","timestamp":"2026-03-04T08:32:26.635Z"},{"error":"Error: {\"message\":\"Failed to export 4 events (status=429, code=ERR_BAD_REQUEST, Request failed with status code 429)\",\"originalLine\":\"6264\",\"originalColumn\":\"1713\",\"line\":\"6264\",\"column\":\"1713\",\"sourceURL\":\"/$bunfs/root/claude\",\"stack\":\"Error: Failed to export 4 events (status=429, code=ERR_BAD_REQUEST, Request failed with status code 429)\\n    at doExport (/$bunfs/root/claude:6264:1713)\\n    at processTicksAndRejections (native:7:39)\",\"name\":\"Error\"}\n    at error (/$bunfs/root/claude:2402:25029)\n    at <anonymous> (/$bunfs/root/claude:119:92465)\n    at A4D (/$bunfs/root/claude:119:93009)\n    at <anonymous> (…

Note: Content was truncated.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗