This question originally came up in our Slack community and the thread has been consolidated here for long-term reference.
I’m self-hosting LiveKit on Ubuntu VM behind Caddy reverse proxy. The LiveKit server and token generator are working, but my frontend can’t connect.
Browser shows:
- WebSocket to
wss://domain.com/rtc opens then closes instantly
- GET
/rtc/rtc/validate returns 404
- ICE connection state goes from
new → closed immediately
LiveKit logs show it fails to detect external IP. Should I set rtc.use_external_ip: true and external_ip in livekit.yaml?
There were a couple of root causes found here:
1. Duplicate /rtc in URL: The URL was wss://domain.com/rtc/rtc - the /rtc gets appended automatically, so remove it from your base URL configuration.
2. External IP detection: The server couldn’t discover or advertise its external IP properly, causing ICE/DTLS handshake failures.
Debugging tips:
- Use
chrome://webrtc-internals/ in one tab while connecting in another - this gives you all WebRTC debug info in real-time
- Check what ICE candidates are being advertised
- Verify your websocket URL is correct and DNS is resolving properly
Common causes of ICE failures:
- VPN interference - disable VPN for testing
- Missing or incorrect
external_ip configuration
- TURN not configured when needed
For production environments, discuss TURN/STUN configuration options to ensure reliable connectivity.