Voice Debugging
Steps for diagnosing voice transmission issues
When voice works locally but other peers don't hear anything, the issue is usually in the WebRTC connection path (ICE / UDP reachability) or SFU forwarding.
Checklist
1) Check SFU logs
docker logs <sfu-container-name> -fLook for:
- server registration
- client joins
- forwarding / RTP activity
- connection state changes
2) Check server logs
docker logs <server-container-name> -fLook for:
- SFU client connect status
- room registration
- voice channel join/leave events
3) Check browser console
Open dev tools and look for:
- ICE connection failures
- SFU websocket connection issues
- audio track errors
4) Verify SFU health endpoint
curl -I http://localhost:5005/health5) Verify STUN + UDP configuration
Ensure STUN is configured:
STUN_SERVERS="stun:stun.l.google.com:19302,stun:stun1.l.google.com:19302"And pin a dedicated UDP port range on the SFU (and open it publicly):
ICE_UDP_PORT_MIN=10000
ICE_UDP_PORT_MAX=10019If the SFU is behind NAT / has multiple NICs, set the public IP it should advertise:
ICE_ADVERTISE_IP=203.0.113.10Interactive test steps
Use these steps in order when debugging a voice channel join.
Step 1 -- verify voice channel click handler
- Open browser dev tools (F12)
- Go to Console
- Click on a voice channel
- Look for messages like:
VOICE CHANNEL CLICK DEBUG: ...
Proceeding with new connection attempt
Room access granted: { room_id: "...", join_token: "...", sfu_url: "..." }If you don't see these messages, the click handler isn't running or the channel type isn't set to voice.
Step 2 -- check server logs
After clicking a voice channel, check server logs for room-access messages. If they're missing, the room request event isn't reaching the server -- check WebSocket connectivity.
Step 3 -- verify SFU is reachable
curl -I http://localhost:5005/healthStep 4 -- verify microphone permissions
Run in the browser console:
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
console.log("Microphone access granted:", stream);
console.log("Audio tracks:", stream.getAudioTracks());
stream.getTracks().forEach(track => track.stop());
})
.catch(err => console.error("Microphone error:", err));Step 5 -- sanity-check WebRTC + STUN
console.log("RTCPeerConnection supported:", !!window.RTCPeerConnection);
const pc = new RTCPeerConnection({ iceServers: [{ urls: "stun:stun.l.google.com:19302" }] });
console.log("WebRTC configuration test passed");
pc.close();What to report
When asking for help, include:
- SFU logs (last ~50 lines)
- server logs (last ~50 lines)
- browser console errors
- STUN config and SFU UDP port range
- steps to reproduce