AlexxIT/go2rtc · error
webrtc: can't get public IP
Error message
webrtc: can't get public IP
What it means
pkg/webrtc GetCachedPublicIP returns the public IP used for WebRTC candidates, resolving it via external STUN-like lookups and caching the result for ~5 minutes. If none of the lookups succeed and nothing valid is cached, it returns this error — the machine effectively has no discoverable public IP, which breaks NAT traversal.
Solutions
- Enable outbound network access so public-IP lookup endpoints are reachable
- Configure the server's own IP with a static/NAT1-to-1 public IP in the config (webrtcIPsFromInterfaces / webrtcAdditionalHosts) and skip auto-lookup
- Check DNS resolution and firewall rules on the host
- Retry later — the cache may be repopulated once connectivity is restored
Example fix
// mediamtx.yml // before (auto-detect fails on isolated host) // after webrtcAdditionalHosts: [203.0.113.10] # explicit public IP instead of lookup
Defensive patterns
Strategy: fallback
Try / catch
ip, err := webrtc.GetCachedPublicIP()
if err != nil {
// fall back to configured static public IP or disable WebRTC
ip = configuredPublicIP
} Prevention
- Configure a static public IP (webrtcAdditionalHosts) on hosts without outbound access
- Monitor outbound connectivity before starting the server in containers/air-gapped networks
When it happens
Trigger: Calling GetCachedPublicIP (directly or through Host / LookupIP) when all public-IP queries fail — no outbound internet access, DNS failure, all lookup endpoints unreachable, or a machine with only private addresses behind strict NAT.
Common situations: Running the server in an isolated Docker network or air-gapped environment; firewall blocking outbound UDP/HTTP to IP-lookup services; cloud instance with no egress yet; wrong DNS setup.
Related errors
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/ea7a05b1cd0298cc.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/webrtc/helpers.go:239
return xorAddr.IP, nil
}
var cachedIP net.IP
var cachedTS time.Time
func GetCachedPublicIP(stuns ...string) (net.IP, error) {
if now := time.Now(); now.After(cachedTS) {
for _, addr := range stuns {
if ip, _ := GetPublicIP(addr); ip != nil {
cachedIP = ip
cachedTS = now.Add(time.Minute * 5)
return ip, nil
}
}
}
if cachedIP == nil {
return nil, errors.New("webrtc: can't get public IP")
}
return cachedIP, nil
}
func IsIP(host string) bool {
for _, i := range host {
if i >= 'A' {
return false
}
}
return true
}
func MimeType(codec *core.Codec) string {
switch codec.Name {
case core.CodecH264:
return webrtc.MimeTypeH264
case core.CodecH265:View on GitHub (pinned to c245815e75)