{"record":{"id":"ea7a05b1cd0298cc","repo":"AlexxIT/go2rtc","slug":"webrtc-can-t-get-public-ip","errorCode":null,"errorMessage":"webrtc: can't get public IP","messagePattern":"webrtc: can't get public IP","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/webrtc/helpers.go","lineNumber":239,"sourceCode":"\n\treturn xorAddr.IP, nil\n}\n\nvar cachedIP net.IP\nvar cachedTS time.Time\n\nfunc GetCachedPublicIP(stuns ...string) (net.IP, error) {\n\tif now := time.Now(); now.After(cachedTS) {\n\t\tfor _, addr := range stuns {\n\t\t\tif ip, _ := GetPublicIP(addr); ip != nil {\n\t\t\t\tcachedIP = ip\n\t\t\t\tcachedTS = now.Add(time.Minute * 5)\n\t\t\t\treturn ip, nil\n\t\t\t}\n\t\t}\n\t}\n\tif cachedIP == nil {\n\t\treturn nil, errors.New(\"webrtc: can't get public IP\")\n\t}\n\treturn cachedIP, nil\n}\n\nfunc IsIP(host string) bool {\n\tfor _, i := range host {\n\t\tif i >= 'A' {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc MimeType(codec *core.Codec) string {\n\tswitch codec.Name {\n\tcase core.CodecH264:\n\t\treturn webrtc.MimeTypeH264\n\tcase core.CodecH265:","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/webrtc/helpers.go#L221-L257","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// mediamtx.yml\n// before (auto-detect fails on isolated host)\n// after\nwebrtcAdditionalHosts: [203.0.113.10]  # explicit public IP instead of lookup","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"ip, err := webrtc.GetCachedPublicIP()\nif err != nil {\n    // fall back to configured static public IP or disable WebRTC\n    ip = configuredPublicIP\n}","preventionTips":["Configure a static public IP (webrtcAdditionalHosts) on hosts without outbound access","Monitor outbound connectivity before starting the server in containers/air-gapped networks"],"tags":["webrtc","network","nat","public-ip"],"backgroundTag":"network-request-failed","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}