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

  1. Verify the hostname resolves with dig/nslookup (or getent hosts) on the same machine
  2. Check /etc/resolv.conf and DNS server reachability; try a public resolver to compare
  3. Use an IP literal instead of a hostname in the WebRTC/candidate URL if the host is static
  4. Confirm the device actually publishes its DNS record (mDNS/local zone) and is online
  5. 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

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)