claudecodeui icon indicating copy to clipboard operation
claudecodeui copied to clipboard

WebSocket Configuration Issue with Tailscale Network Access

Open guy746 opened this issue 6 months ago • 1 comments

● WebSocket Configuration Issue with Tailscale Network Access

Issue Summary

The Claude Code UI WebSocket backend failed to work when accessed via Tailscale network (100.x IP addresses), despite HTTP API calls functioning correctly. This affected AI chat functionality for users accessing the service through Tailscale VPN.

Root Cause

The /api/config endpoint in server/index.js was hardcoding the WebSocket URL using a static IP detection method:

// PROBLEMATIC CODE (Lines 192-201) const serverIP = getServerIP(); // Returns first non-localhost IP (192.168.1.146) const host = ${serverIP}:${PORT}; const wsUrl = ${protocol}://${host}; // Always returned ws://192.168.1.146:3008

Problem: When users accessed via Tailscale (http://100.117.241.55:3009), the frontend received a WebSocket URL pointing to the local network IP (ws://192.168.1.146:3008) instead of the Tailscale IP (ws://100.117.241.55:3008), causing WebSocket connections to fail.

Impact

  • ✅ Working: HTTP API calls, file operations, authentication
  • ❌ Broken: Real-time chat, AI interactions, live updates
  • Affected Networks: Tailscale, remote access, any non-local-network access

Solution

Modified the /api/config endpoint to dynamically determine the WebSocket URL based on the client's request host:

// FIXED CODE app.get('/api/config', authenticateToken, (req, res) => { const requestHost = req.get('host'); // Get host from request header const protocol = req.protocol === 'https' || req.get('x-forwarded-proto') === 'https' ? 'wss' : 'ws';

const hostname = requestHost.split(':')[0]; // Extract hostname
const wsHost = `${hostname}:${PORT}`; // Use same hostname with backend

port

res.json({
  serverPort: PORT,
  wsUrl: `${protocol}://${wsHost}` // Dynamic WebSocket URL
});

});

Fix Results

Before: WebSocket URL was always ws://192.168.1.146:3008After: WebSocket URL adapts to request:

  • Local: ws://localhost:3008
  • WiFi: ws://192.168.1.146:3008
  • Tailscale: ws://100.117.241.55:3008

Files Modified

  • File: /server/index.js
  • Lines: 190-205 (API config endpoint)
  • Change: Dynamic host detection instead of static IP resolution

Testing Verified

  • ✅ WebSocket connections via Tailscale network
  • ✅ AI chat functionality working
  • ✅ Backward compatibility with local/WiFi access
  • ✅ Service auto-restart on boot maintained

Recommendation

This fix should be applied to the upstream codebase to support multi-network deployments including VPN access, Docker containers, and cloud deployments where the service may be accessed through different network interfaces.

save in md file in the claudecodeui folder

● Write(claudecodeui/claudecodeui/WEBSOCKET_TAILSCALE_FIX.md) ⎿  Wrote 91 lines to claudecodeui/claudecodeui/WEBSOCKET_TAILSCALE_FIX.md # WebSocket Configuration Issue with Tailscale Network Access ## Issue Summary The Claude Code UI WebSocket backend failed to work when accessed via Tailscale network (100.x IP addresses), despite HTTP API calls functioning correctly. This affected AI chat functionality for users accessing the service through Tailscale VPN. ## Root Cause The /api/config endpoint in server/index.js was hardcoding the WebSocket URL using a static IP detection method: … +81 lines (ctrl+r to expand)

guy746 avatar Jul 12 '25 16:07 guy746

This is now fixed in the latest commit. Can you check?

viper151 avatar Jul 13 '25 13:07 viper151