AlexxIT/go2rtc · error
can't resolve
Error message
can't resolve: %s
What it means
Returned by the public LookupIP helper in pkg/webrtc/helpers.go. It splits the address at the last-seen ':' separator, performs net.LookupIP on the host part, and if the lookup succeeds but returns zero IPs, it reports that the host cannot be resolved. It means the resolver returned no addresses for the hostname embedded in the WebRTC address.
Solutions
- Verify the hostname resolves with dig/nslookup (or getent hosts) on the same machine
- Check /etc/resolv.conf and DNS server reachability; try a public resolver to compare
- Use an IP literal instead of a hostname in the WebRTC/candidate URL if the host is static
- Confirm the device actually publishes its DNS record (mDNS/local zone) and is online
- Inspect the address format — ensure there is a ':' separator so the host part is extracted correctly
Example fix
// before
ip, err := webrtc.LookupIP("dead-camera-host.local:8555") // zero IPs -> "can't resolve"
// after
if _, err := net.LookupHost("dead-camera-host.local"); err != nil || len(hostIPs) == 0 {
// fall back to IP literal or fix DNS first
}
ip, err := webrtc.LookupIP("192.168.1.42:8555") Defensive patterns
Strategy: validation
Validate before calling
// Go: verify the host resolves before calling LookupIP
host := address[:strings.IndexByte(address, ':')]
ips, err := net.LookupHost(host)
if err != nil || len(ips) == 0 {
return fmt.Errorf("host %q unresolvable, use IP or fix DNS", host)
} Type guard
func isResolvable(host string) bool { ips, err := net.LookupHost(host); return err == nil && len(ips) > 0 } Try / catch
ip, err := webrtc.LookupIP(addr)
if err != nil {
log.Warnf("lookup failed for %s: %v; falling back to literal IP", addr, err)
ip = fallbackIP
} Prevention
- Use IP literals for static devices in candidate URLs
- Run dig/nslookup during deployment to verify DNS entries
- Keep local DNS/mDNS zones healthy for .local names
- Monitor resolv.conf and DNS server reachability
When it happens
Trigger: Calling LookupIP with an "host:port"-style address whose host part is a hostname that DNS resolves to an empty answer (e.g. an NAPTR/A-record-less name), or a malformed host that yields no records despite no lookup error.
Common situations: SDP candidates or config URLs referencing internal hostnames not present in DNS; stale mDNS/local names after the camera went offline; DNS server answering NOERROR with zero records; typo'd host in webrtc config.
Related errors
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/201090403cdabe99.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/webrtc/helpers.go:181
if strings.HasPrefix(address, "stun:") {
ip, err := GetCachedPublicIP()
if err != nil {
return "", err
}
return ip.String() + address[4:], nil
}
if IsIP(address) {
return address, nil
}
i := strings.IndexByte(address, ':')
ips, err := net.LookupIP(address[:i])
if err != nil {
return "", err
}
if len(ips) == 0 {
return "", fmt.Errorf("can't resolve: %s", address)
}
return ips[0].String() + address[i:], nil
}
// GetPublicIP example from https://github.com/pion/stun
func GetPublicIP(address string) (net.IP, error) {
conn, err := net.Dial("udp", address)
if err != nil {
return nil, err
}
c, err := stun.NewClient(conn)
if err != nil {
return nil, err
}
if err = conn.SetDeadline(time.Now().Add(time.Second * 3)); err != nil {View on GitHub (pinned to c245815e75)