[Config Support]: WebRTC vs. MSE in LAN vs. WAN with docker overlay networks #20243
Replies: 9 comments 10 replies
-
go2rtc:
webrtc:
candidates:
- 192.168.0.91:8555 # Your LAN IP
- stun:8555
filters:
candidates: []This approach was confirmed to prevent the container IP from appearing as a candidate(1), (2).
References for further reading:
📚 Sources:
Have another question? Just tag @inkeep. |
Beta Was this translation helpful? Give feedback.
-
|
On LAN, Frigate's Live View defaults to MSE streaming when go2rtc is configured, unless a feature requiring WebRTC (like two-way audio) is active(1). WebRTC is only automatically selected when MSE fails, when using two-way talk, or if the browser/device doesn't support MSE(1). On WAN, if MSE is unavailable or fails, Frigate will fall back to WebRTC, which is likely why you consistently see WebRTC on WAN but not on LAN(1). If you want WebRTC to be used on LAN all the time, there is no configuration option documented to force WebRTC as the default over MSE—Frigate prefers MSE for compatibility and efficiency, only switching to WebRTC when necessary(1). This behavior is by design. 📚 Sources: Have another question? Just tag @inkeep. |
Beta Was this translation helpful? Give feedback.
-
📚 Sources: Have another question? Just tag @inkeep. |
Beta Was this translation helpful? Give feedback.
-
|
There is no documented method in Frigate, Traefik, or Pi-hole to selectively block or disable MSE for LAN clients. Frigate's Live View will always attempt MSE first when available, and only fall back to WebRTC if MSE fails (for example, if the browser cannot access the stream endpoint or if the stream is not compatible). The documentation does not provide a supported configuration or reverse proxy rule to intentionally break or block MSE for LAN users so that WebRTC is always used instead. This behavior is by design and cannot be changed using documented configuration options for Frigate, Traefik, or DNS with Pi-hole(1). 📚 Sources: Have another question? Just tag @inkeep. |
Beta Was this translation helpful? Give feedback.
-
|
There is no documented way to use the WebRTC candidate list to force all LAN clients through your reverse proxy in a way that disables MSE in Frigate. The candidate list for WebRTC only controls which IPs and ports are advertised for WebRTC negotiation—it does not affect or block MSE. MSE remains available as long as clients can directly access the Frigate server’s MSE endpoints over the network, regardless of your reverse proxy or WebRTC candidate settings. There is no supported configuration in Frigate, Traefik, or DNS (Pi-hole) to make MSE unavailable by only manipulating WebRTC candidates(1). Have another question? Just tag @inkeep. |
Beta Was this translation helpful? Give feedback.
-
|
MSE (Media Source Extensions) will be unavailable in Frigate and cause a fallback to WebRTC in these documented situations:
If any of these conditions occur, Frigate will automatically attempt to use WebRTC for live streaming if your configuration enables it(1). 📚 Sources: Have another question? Just tag @inkeep. |
Beta Was this translation helpful? Give feedback.
-
|
Ref. inkeep's explanation of MSE being the favored choice, I must urge the developers of Frigate to make it possible to force WebRTC. It is superior and the fact that I have to try get something out of inkeep to get some idea of how to achieve a better user experience by making MSE unavailable is stupid. |
Beta Was this translation helpful? Give feedback.
-
|
If you set WebRTC as the preferred mode in the Home Assistant Advanced Camera Card and get no stream, this is not due to go2rtc insisting on MSE. Frigate and go2rtc do not block WebRTC, but WebRTC only works if all required network, codec, and signaling conditions are met. If WebRTC fails, it’s typically because:
To fix this:
There is no documented way to force go2rtc or Frigate to always use WebRTC if the required network or codec conditions are not met. Frigate will only use WebRTC if it can successfully negotiate a connection; otherwise, the stream will fail in the card(1), (2). Have another question? Just tag @inkeep. |
Beta Was this translation helpful? Give feedback.
-
|
If WebRTC works on WAN but not on LAN in the HA Advanced Camera Card, the most likely reasons are: Network Configuration Issues:
Browser/Client Differences:
Reverse Proxy Configuration:
ICE Candidate Issues:
Home Assistant Add-on Specific:
To troubleshoot, you could try:
📚 Sources:
Have another question? Just tag @inkeep. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Describe the problem you are having
Summary
WebRTC in Frigate works over WAN (via Traefik + domain) but not on LAN. On LAN, Chrome webrtc-internals shows Docker overlay IPs advertised as ICE candidates, which are unreachable for clients. I’ve explicitly configured Frigate/go2rtc to only use my host IP/domain, but the container still includes Docker network IPs as candidates.
Environment
Version
0.16.1-e664cb2
Frigate config file
Relevant Frigate log output
Relevant go2rtc log output
Frigate stats
{"cameras":{"main_entrance":{"camera_fps":5.0,"process_fps":5.0,"skipped_fps":0.0,"detection_fps":0.0,"detection_enabled":true,"pid":546,"capture_pid":593,"ffmpeg_pid":599,"audio_rms":0.0,"audio_dBFS":0.0},"terrace":{"camera_fps":5.1,"process_fps":5.1,"skipped_fps":0.0,"detection_fps":0.0,"detection_enabled":true,"pid":557,"capture_pid":605,"ffmpeg_pid":611,"audio_rms":0.0,"audio_dBFS":0.0},"babycam":{"camera_fps":5.1,"process_fps":5.0,"skipped_fps":0.0,"detection_fps":8.0,"detection_enabled":true,"pid":559,"capture_pid":617,"ffmpeg_pid":623,"audio_rms":19.2042,"audio_dBFS":-64.6411},"imac":{"camera_fps":5.1,"process_fps":5.1,"skipped_fps":0.0,"detection_fps":0.5,"detection_enabled":true,"pid":573,"capture_pid":627,"ffmpeg_pid":633,"audio_rms":349.8458,"audio_dBFS":-39.4315}},"detectors":{"onnx":{"inference_speed":15.15,"detection_start":1758984277.40109,"pid":503}},"detection_fps":8.5,"embeddings":{},"gpu_usages":{"NVIDIA GeForce RTX 2060":{"gpu":"6.0%","mem":"23.52%","enc":"0.0%","dec":"3.0%"}},"cpu_usages":{"frigate.full_system":{"cpu":"32.3","mem":"68.4"},"1":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"/package/admin/s6/command/s6-svscan -d4 -- /run/service"},"17":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise s6-linux-init-shutdownd"},"18":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"/package/admin/s6-linux-init/command/s6-linux-init-shutdownd -d3 -c /run/s6/basedir -g 3000 -C -B"},"27":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise certsync"},"28":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise go2rtc-log"},"29":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise s6rc-fdholder"},"30":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise go2rtc-healthcheck"},"31":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise s6rc-oneshot-runner"},"32":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise certsync-log"},"33":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise nginx-log"},"34":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise nginx"},"35":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise go2rtc"},"36":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise frigate"},"37":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-supervise frigate-log"},"48":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"/package/admin/s6-2.13.2.0/command/s6-fdholderd -1 -n 256 -i data/rules"},"49":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"/package/admin/s6/command/s6-ipcserverd -1 -- /package/admin/s6/command/s6-ipcserver-access -v0 -E -l0 -i data/rules -- /package/admin/s6/command/s6-sudod -t 30000 -- /package/admin/s6-rc/command/s6-rc-oneshot-run -l ../.. --"},"95":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-log -b -- T 1 n0 s10000000 T /dev/shm/logs/nginx"},"100":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-log -b -- T 1 n0 s10000000 T /dev/shm/logs/frigate"},"103":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-log -b -- T 1 n0 s10000000 T /dev/shm/logs/certsync"},"104":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"s6-log -b -- T 1 n0 s10000000 T /dev/shm/logs/go2rtc"},"128":{"cpu":"10.8","cpu_average":"6","mem":"1.3","cmdline":"/usr/local/go2rtc/bin/go2rtc -config=/dev/shm/go2rtc.yaml"},"136":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"bash ./run.user go2rtc-healthcheck"},"137":{"cpu":"15.9","cpu_average":"9","mem":"4.4","cmdline":"python3 -u -m frigate"},"143":{"cpu":"0.0","cpu_average":"0","mem":"0.1","cmdline":"nginx: master process nginx"},"191":{"cpu":"0.1","cpu_average":"0","mem":"0.0","cmdline":"nginx: worker process"},"192":{"cpu":"0.0","cpu_average":"0","mem":"0.1","cmdline":"nginx: worker process"},"193":{"cpu":"0.0","cpu_average":"0","mem":"0.1","cmdline":"nginx: worker process"},"194":{"cpu":"0.1","cpu_average":"0","mem":"0.1","cmdline":"nginx: worker process"},"199":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"nginx: cache manager process"},"347":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"bash ./run.user certsync"},"376":{"cpu":"0.0","cpu_average":"0","mem":"1.0","cmdline":"python3 -u -m frigate"},"478":{"cpu":"2.2","cpu_average":"2","mem":"2.7","cmdline":"frigate.recording_manager"},"490":{"cpu":"0.7","cpu_average":"0","mem":"2.1","cmdline":"frigate.review_segment_manager"},"503":{"cpu":"11.6","cpu_average":"9","mem":"2.9","cmdline":"frigate.detector.onnx"},"525":{"cpu":"3.4","cpu_average":"2","mem":"2.5","cmdline":"frigate.output "},"546":{"cpu":"2.0","cpu_average":"2","mem":"1.3","cmdline":"frigate.process:main_entrance"},"557":{"cpu":"2.3","cpu_average":"2","mem":"1.5","cmdline":"frigate.process:terrace"},"559":{"cpu":"12.8","cpu_average":"6","mem":"2.6","cmdline":"frigate.process:babycam"},"573":{"cpu":"2.4","cpu_average":"5","mem":"1.9","cmdline":"frigate.process:imac "},"593":{"cpu":"0.8","cpu_average":"0","mem":"1.2","cmdline":"frigate.capture:main_entrance"},"599":{"cpu":"2.3","cpu_average":"2","mem":"1.2","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -hide_banner -loglevel warning -threads 2 -hwaccel cuda -hwaccel_output_format cuda -user_agent FFmpeg Frigate/0.16.1-e664cb2 -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -rtsp_transport tcp -timeout 10000000 -use_wallclock_as_timestamps 1 -i rtsp://127.0.0.1:8554/main_entrance_low_res -r 5 -vf fps=5,scale_cuda=w=640:h=360,hwdownload,format=nv12,eq=gamma=1.4:gamma_weight=0.5 -threads 2 -f rawvideo -pix_fmt yuv420p pipe:"},"604":{"cpu":"4.2","cpu_average":"4","mem":"0.2","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -hide_banner -loglevel warning -threads 2 -user_agent FFmpeg Frigate/0.16.1-e664cb2 -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -rtsp_transport tcp -timeout 10000000 -use_wallclock_as_timestamps 1 -i rtsp://127.0.0.1:8554/main_entrance?video&audio -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v copy -c:a aac /tmp/cache/main_entrance@%Y%m%d%H%M%S%z.mp4"},"605":{"cpu":"6.4","cpu_average":"6","mem":"1.3","cmdline":"frigate.capture:terrace"},"611":{"cpu":"14.6","cpu_average":"14","mem":"2.1","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -hide_banner -loglevel warning -threads 2 -hwaccel cuda -hwaccel_output_format cuda -user_agent FFmpeg Frigate/0.16.1-e664cb2 -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -rtsp_transport tcp -timeout 10000000 -use_wallclock_as_timestamps 1 -i rtsp://127.0.0.1:8554/terrace?video&audio -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v copy -c:a aac /tmp/cache/terrace@%Y%m%d%H%M%S%z.mp4 -r 5 -vf fps=5,scale_cuda=w=2304:h=1296,hwdownload,format=nv12,eq=gamma=1.4:gamma_weight=0.5 -threads 2 -f rawvideo -pix_fmt yuv420p pipe:"},"617":{"cpu":"4.6","cpu_average":"4","mem":"1.3","cmdline":"frigate.capture:babycam"},"623":{"cpu":"12.3","cpu_average":"12","mem":"1.8","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -hide_banner -loglevel warning -threads 2 -hwaccel cuda -hwaccel_output_format cuda -user_agent FFmpeg Frigate/0.16.1-e664cb2 -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -rtsp_transport tcp -timeout 10000000 -use_wallclock_as_timestamps 1 -i rtsp://127.0.0.1:8554/babycam?video&audio -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v copy -c:a aac /tmp/cache/babycam@%Y%m%d%H%M%S%z.mp4 -r 5 -vf fps=5,scale_cuda=w=1920:h=1080,hwdownload,format=nv12,eq=gamma=1.4:gamma_weight=0.5 -threads 2 -f rawvideo -pix_fmt yuv420p pipe:"},"627":{"cpu":"1.7","cpu_average":"1","mem":"1.2","cmdline":"frigate.capture:imac "},"633":{"cpu":"12.4","cpu_average":"11","mem":"1.5","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -hide_banner -loglevel warning -threads 2 -hwaccel cuda -hwaccel_output_format cuda -user_agent FFmpeg Frigate/0.16.1-e664cb2 -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -rtsp_transport tcp -timeout 10000000 -use_wallclock_as_timestamps 1 -i rtsp://127.0.0.1:8554/imac?video&audio -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v copy -c:a aac /tmp/cache/imac@%Y%m%d%H%M%S%z.mp4 -r 5 -vf fps=5,scale_cuda=w=960:h=720,hwdownload,format=nv12,eq=gamma=1.4:gamma_weight=0.5 -threads 2 -f rawvideo -pix_fmt yuv420p pipe:"},"637":{"cpu":"1.3","cpu_average":"0","mem":"1.9","cmdline":"python3 -u -m frigate"},"654":{"cpu":"0.9","cpu_average":"0","mem":"0.1","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -vn -threads 1 -hide_banner -loglevel warning -threads 2 -user_agent FFmpeg Frigate/0.16.1-e664cb2 -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -rtsp_transport tcp -timeout 10000000 -use_wallclock_as_timestamps 1 -i rtsp://127.0.0.1:8554/babycam?video&audio -threads 1 -f s16le -ar 16000 -ac 1 -y pipe:"},"668":{"cpu":"3.0","cpu_average":"2","mem":"0.1","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -vn -threads 1 -hide_banner -loglevel warning -threads 2 -user_agent FFmpeg Frigate/0.16.1-e664cb2 -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -rtsp_transport tcp -timeout 10000000 -use_wallclock_as_timestamps 1 -i rtsp://127.0.0.1:8554/imac?video&audio -threads 1 -f s16le -ar 16000 -ac 1 -y pipe:"},"839":{"cpu":"0.0","cpu_average":"0","mem":"0.1","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -threads 1 -f rawvideo -pix_fmt yuv420p -video_size 640x360 -i pipe: -threads 1 -f mpegts -s 1280x720 -codec:v mpeg1video -q 8 -bf 0 pipe:"},"846":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -threads 1 -f rawvideo -pix_fmt yuv420p -video_size 2304x1296 -i pipe: -threads 1 -f mpegts -s 1280x720 -codec:v mpeg1video -q 8 -bf 0 pipe:"},"853":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -threads 1 -f rawvideo -pix_fmt yuv420p -video_size 1920x1080 -i pipe: -threads 1 -f mpegts -s 1280x720 -codec:v mpeg1video -q 8 -bf 0 pipe:"},"860":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -threads 1 -f rawvideo -pix_fmt yuv420p -video_size 960x720 -i pipe: -threads 1 -f mpegts -s 960x720 -codec:v mpeg1video -q 8 -bf 0 pipe:"},"867":{"cpu":"0.0","cpu_average":"0","mem":"0.3","cmdline":"/usr/lib/ffmpeg/7.0/bin/ffmpeg -threads 1 -f rawvideo -pix_fmt yuv420p -video_size 1280x720 -i pipe: -threads 1 -f mpegts -s 1280x720 -codec:v mpeg1video -q 8 -bf 0 pipe:"},"209779":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"sleep 9999"},"220623":{"cpu":"0.0","cpu_average":"0","mem":"0.0","cmdline":"sleep 30s"}},"service":{"uptime":73230,"version":"0.16.1-e664cb2","latest_version":"0.16.1","storage":{"/media/frigate/recordings":{"total":543704.0,"used":41008.0,"free":500822.0,"mount_type":"nfs4"},"/media/frigate/clips":{"total":543704.0,"used":41008.0,"free":500822.0,"mount_type":"nfs4"},"/tmp/cache":{"total":953.7,"used":40.5,"free":913.2,"mount_type":"tmpfs"},"/dev/shm":{"total":3000.0,"used":431.3,"free":2568.7,"mount_type":"tmpfs"}},"temperatures":{},"last_updated":1758984277},"processes":{"recording":{"pid":478},"review_segment":{"pid":490},"go2rtc":{"pid":128},"audio_detector":{"pid":637}}}Operating system
Debian
Install method
Docker Compose
docker-compose file or Docker CLI command
Object Detector
TensorRT
Screenshots of the Frigate UI's System metrics pages
No response
Any other information that may be helpful
Observed behavior
In Home Assistant
LAN:
WAN:
In Frigate UI
LAN and WAN:
General
On LAN, Chrome shows candidates like:
10.10.20.30(docker overlay IP)10.20.30.40(docker overlay IP)192.168.0.91(host LAN IP)Even with explicit candidates, Docker overlay IPs are still included.
local-candidateis never set in Chrome’s WebRTC internals.On WAN, everything works fine — streams load without forwarding
8555.What I have tried
Explicit candidates
→ Still shows Docker overlay IPs in Chrome.
Using host: and port:
→ Did not change behavior (not sure this is valid, chatgpt suggested it).
Removing stun:8555
→ No effect, overlay IPs still appear as candidates.
My pihole redirects all *.mydomian.com to Traefik,
→ Still didn't get the WAN behavior from LAN as I was hoping it would do.
Expected behavior
Questions
stun:webrtc.example.com:443the correct approach when running behind Traefik without exposing8555directly?8555) but LAN falls back to Docker IPs?local-candidatein Chrome an indicator of misconfiguration in go2rtc/Frigate?This used to work before I changed by router, but I changed my router from a TP-link to a TP-link and I set the same settings as before. But clearly there is some gap in my networking knowledge that stops me from understanding what I am doing wrong here.
Please help because viewing the stream in Home Assistant over MSE is not a good experience. Sometimes buffering, stream pauses, more latency, etc.
Beta Was this translation helpful? Give feedback.
All reactions