WebRTC Test Guide
A reference for the desktest.net WebRTC Test. Covers how it checks STUN reachability, ICE gathering, and an end-to-end peer connection, how to read the verdict, and what to do when video calls will not connect.
What does the WebRTC Test check?
The tool drives the browser's RTCPeerConnection API against a set of public STUN servers, then negotiates a full connection between two peers inside the same page. It does not call getUserMedia, so no camera or microphone permission prompt appears. Works on Chrome, Edge, Firefox, and Safari. The three steps run in order:
- Feature detection. Confirms
RTCPeerConnection,getUserMedia, andgetDisplayMediaexist, then enumerates the audio and video codecs the browser advertises throughRTCRtpReceiver.getCapabilities()(H264, VP8, VP9, AV1, Opus, and so on) and notes whether insertable streams are supported. - STUN reachability. Creates an
RTCPeerConnectionpointed at four public STUN servers (Google, Cloudflare, Mozilla), opens a data channel, creates an offer, and listens for ICE candidates for about 5 seconds. Each candidate is categorized as host (your local network), srflx (your public address as seen by STUN), prflx, or relay (TURN). A pass needs at least one host and one srflx candidate, which proves outbound UDP to a STUN server left and came back. - End-to-end negotiation. Spins up two
RTCPeerConnectionobjects in the same page, shuttles the offer, answer, and ICE candidates between them in JavaScript (no signaling server), waits for both to reachconnected, then round-trips a message over a data channel. This proves the local WebRTC stack can negotiate a full session without depending on any external peer.
When should I run this?
- Before a video call on a new machine or network. Confirm the browser can actually reach out and negotiate before you join.
- "Camera works but the meeting will not connect." The webcam preview looks fine, yet calls drop at "connecting." That is almost never the camera; it is UDP or WebRTC being blocked, which this test isolates.
- Guest wifi, hotel, or a locked-down corporate network. These are the networks that silently drop the UDP a call needs.
- On a VPN. Split-tunnel configurations can route media differently from signaling and break calls that work off-VPN.
- Help-desk triage. Decide quickly whether the problem is Zoom, the browser, or the firewall.
- Provisioning a remote worker's laptop. Verify conferencing readiness before it ships.
Reading the results
Step 1 lists the detected codecs as chips and flags whether getUserMedia and getDisplayMedia (screen share) are available.
Step 2 shows the gathered candidates by type with counts. host is your local network, srflx is your public address discovered through STUN, and relay would be a TURN candidate (the test uses no TURN server, so relay stays at zero). Your public IP is shown once at the top; the per-candidate list redacts public addresses so a screenshot does not leak them. The raw SDP offer and answer are available in the Show SDP dropdowns.
Step 3 shows the live connection and ICE state of both in-page peers, the setup time, and the data-channel round-trip time.
Each step row carries a status badge: Pending, Running, Pass, Warn, or Fail. On warn or fail the row expands with the diagnosis. The verdict panel at the top names the most likely cause and a recommended next step. Copy Diagnostic Report copies a plain-text summary: browser, codecs, candidate counts by type, per-step results, timings, and the diagnosis tag. Paste it into a ticket.
Common failures and fixes
The tool produces a named diagnosis for every failure path. Two of them look similar but mean opposite things, so read carefully.
webrtc-unsupported: WebRTC is not supported
No RTCPeerConnection object exists at all. The browser is too old, sandboxed, or running with WebRTC disabled by policy. Update to a current Chrome, Edge, Firefox, or Safari, or check the browser's policy settings.
getusermedia-unsupported: capture is unavailable
getUserMedia is not exposed, usually because the page is served over plain HTTP instead of HTTPS, or the browser is very old. On desktest.net the page is HTTPS, so this points at the browser. Core peer connection can still work; screen share or camera capture will not.
no-candidates: WebRTC is blocked at the browser level
No ICE candidates were gathered at all, not even a host candidate. That is not a firewall; a firewall still lets the browser see its own local addresses. This means WebRTC is disabled inside the browser.
- Retry in an incognito or private window with extensions disabled. Privacy extensions (uBlock Origin's "Prevent WebRTC from leaking local IP", Privacy Badger) and Brave Shields commonly cause this.
- On Firefox, check that
media.peerconnection.enabledistrueinabout:config. - On managed Chrome or Edge, check enterprise policy for a WebRTC block. If one machine fails here while its neighbor passes, it is local policy or an extension, not the network.
only-host: STUN servers are blocked
Local (host) candidates were discovered, but no public STUN endpoint answered, so no srflx candidate appeared. This is the classic corporate-network failure: a firewall is dropping outbound UDP to the STUN ports (3478 and 19302).
- Ask the network admin to allow outbound UDP to those ports.
- If the network refuses UDP as policy, the calling app needs a TURN relay (which can fall back to TCP or TLS on 443). This test includes no TURN server, so
only-hostis the honest result on such networks. - Off the corporate network (phone hotspot, home wifi) the same test usually passes, which confirms the block is the network, not the machine.
setup-timeout: peers did not connect in time
The two in-page peers did not both reach connected within 8 seconds. Usually background-tab throttling, a slow machine, or an extension interfering. Keep this tab in the foreground, close other tabs, disable extensions, and retry.
ice-failed: ICE failed mid-negotiation
One of the in-page peers entered the failed ICE state. Because both peers are in the same tab, a network firewall cannot cause this; a privacy extension or strict policy is blocking candidate exchange even locally. Retry in an incognito window with extensions disabled.
data-channel-failed: message did not round-trip
The peers connected, but the test message did not echo back. Rare, usually a browser bug or extension interference with data channels. Update the browser to the latest version, disable extensions, and retry.
connection-failed: negotiation could not complete
A general local negotiation failure not covered by the cases above. Open the browser console for the specific error and retry.
Warnings: getdisplaymedia-limited and codec-poor
Two conditions show as a yellow Warn rather than a fail, because the call still connects:
getdisplaymedia-limited- screen share (getDisplayMedia) is not exposed. You can still join meetings but cannot share your screen from this browser. Common on older Safari (before 14) and some embedded browsers.codec-poor- the browser reported fewer than two video codecs. Most browsers ship at least VP8, VP9, and H.264; a short list points to a custom or hardened build with codecs stripped, which can limit interop with some peers.
For IT admins
WebRTC needs outbound UDP. Signaling reaches a STUN server on UDP 3478 (Google also uses 19302), the browser learns its public mapping, and media then flows over ephemeral UDP ports. Anything that blocks that UDP breaks calls while leaving web pages working perfectly, which is why "the internet is fine but meetings fail" is such a common ticket.
The signal that matters. An only-host result, with the local network discovered but no srflx, means outbound UDP to STUN is being dropped. Allow outbound UDP egress to the STUN ports, or stand up a TURN relay with a TCP/TLS-443 fallback for networks that refuse UDP as policy. A TURN relay is what production conferencing apps rely on for the strictest networks.
Browser-level blocks. A no-candidates result is local, not network. On managed Chrome and Edge, review WebRTC-related enterprise policies (for example WebRtcUdpPortRange and any policy that disables WebRTC). Privacy extensions and hardened browser builds disable it too. Test a known-good machine on the same network to separate a policy problem from a firewall problem.
mDNS candidates. Modern Chrome and Firefox hide local IPs behind .local mDNS candidates by default. That is expected and does not break connectivity. Where an internal application legitimately needs the real local IP, Chrome's WebRtcLocalIpsAllowedUrls policy can reveal it for specific origins.
Split-tunnel VPN. If calls work off-VPN but fail on it, the VPN is likely routing media differently from signaling or dropping UDP. Check the split-tunnel rules and the VPN's UDP policy.
Native vs browser. Teams and Zoom desktop apps use their own media stacks and port ranges; this tool measures browser WebRTC (Meet, Teams web, Slack Huddles, Zoom web). The firewall UDP rules usually overlap, so a STUN-blocked result is a strong predictor of trouble for the native apps as well.
Behind the scenes
STUN runs over UDP, and UDP emitted by RTCPeerConnection is not governed by the page's Content-Security-Policy connect-src (CSP governs fetch, XHR, and WebSocket, not the raw UDP WebRTC uses). That is why this tool can reach STUN even though the page's CSP lists no external hosts. The four STUN servers are named in the source (app.js) so anyone can see exactly which servers are contacted: Google, Cloudflare, and Mozilla.
The end-to-end step needs no signaling server because both peers live in the same page; the offer, answer, and ICE candidates are handed between them directly in JavaScript. This isolates the local WebRTC stack from any network dependency, so step 3 failing while step 2 passed points at the browser, not the firewall.
Passing step 2 requires a host candidate and a srflx candidate. Host alone proves the stack works locally; srflx proves a packet reached a public STUN server and its reply came back, which is the real-world requirement for a call to connect through NAT.
Your public IP is shown once at the top of step 2; the per-candidate list redacts public addresses so a screenshot does not leak them. The test carries no TURN server, so on a symmetric-NAT or UDP-blocked network the honest result is only-host, and a real deployment would supply its own TURN relay.
Apart from the STUN UDP probes to the four listed servers, nothing leaves the tab: getUserMedia is only feature-detected and never called, there is no telemetry or analytics, and the in-page negotiation is entirely local. Open DevTools, Network tab, to confirm no HTTP requests fire during the run.
Related
- WebRTC Test - the diagnostic itself
- Network Test Guide - check general egress, DNS-over-HTTPS, and WebSocket reachability
- Browser Test Guide - confirm secure context and modern API support
- Microphone Test Guide and Webcam Test Guide - the capture side of a call
- desktest.net home and About desktest.net