AlexxIT/go2rtc · error

wrong candidate

Error message

wrong candidate: ${address}

What it means

pkg/webrtc NewCandidate builds an SDP candidate string from a network type and an address. It requires 'host:port' form — it splits at the last colon to separate host and port. If the address has no colon, there is no port and the function refuses to build a malformed candidate.

Solutions

  1. Pass the address in host:port form, e.g. NewCandidate("udp4", "192.168.1.5:50000")
  2. Append the listening/default port programmatically when the source address has none
  3. Validate the address contains a ':' and the port is numeric before calling

Example fix

// before
candidate, err := webrtc.NewCandidate("udp4", "192.168.1.5")
// after
candidate, err := webrtc.NewCandidate("udp4", "192.168.1.5:50000")
Defensive patterns

Strategy: validation

Validate before calling

if !strings.Contains(address, ":") {
    return fmt.Errorf("candidate address must be host:port, got %q", address)
}
port, err := strconv.Atoi(address[strings.LastIndexByte(address, ':')+1:])
if err != nil || port <= 0 || port > 65535 { /* reject */ }

Type guard

func hasHostPort(addr string) bool {
    i := strings.LastIndexByte(addr, ':')
    if i < 0 { return false }
    p, err := strconv.Atoi(addr[i+1:])
    return err == nil && p > 0 && p <= 65535
}

Prevention

When it happens

Trigger: Calling webrtc NewCandidate with an address string lacking a port, e.g. '192.168.1.5' or 'example.com', instead of '192.168.1.5:50000'.

Common situations: Passing an IP or hostname from config that never had the port appended; parsing candidates from a log and dropping the port portion; using an address string that got truncated (empty string also has no colon).

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/da5fba859018e7c6. Report an issue: GitHub.

Appendix: source

Thrown at pkg/webrtc/helpers.go:134

		if pcma != nil && pcm == nil {
			pcm = pcma.Clone()
			pcm.Name = core.CodecPCM
			media.Codecs = append(media.Codecs, pcm)
		}
		if pcma != nil && pcml == nil {
			pcml = pcma.Clone()
			pcml.Name = core.CodecPCML
			media.Codecs = append(media.Codecs, pcml)
		}
	}

	return medias
}

func NewCandidate(network, address string) (string, error) {
	i := strings.LastIndexByte(address, ':')
	if i < 0 {
		return "", errors.New("wrong candidate: " + address)
	}
	host, port := address[:i], address[i+1:]

	i, err := strconv.Atoi(port)
	if err != nil {
		return "", err
	}

	config := &ice.CandidateHostConfig{
		Network:   network,
		Address:   host,
		Port:      i,
		Component: ice.ComponentRTP,
	}

	if network == "tcp" {
		config.TCPType = ice.TCPTypePassive
	}

View on GitHub (pinned to c245815e75)