router-for-me/CLIProxyAPI · error

codex.live-media-relay UDP port minimum and maximum must bot

Error message

codex.live-media-relay UDP port minimum and maximum must both be set

What it means

Validation error for codex.live-media-relay: exactly one of udp-port-min / udp-port-max was set (the other left at 0). The UDP port range must be either fully unset (ephemeral ports) or fully specified, because the relay reserves a contiguous range for its sessions (two ports per session).

Source

Thrown at internal/config/codex_live.go:77

	if c.MaxSessions > 0 {
		return c.MaxSessions
	}
	return DefaultCodexLiveMediaMaxSessions
}

// Validate verifies the Codex Live media relay configuration.
func (c CodexLiveMediaRelayConfig) Validate() error {
	if !c.Enabled {
		return nil
	}
	if c.MaxSessions < 0 {
		return errors.New("codex.live-media-relay.max-sessions must not be negative")
	}
	if publicIP := strings.TrimSpace(c.PublicIP); publicIP != "" && net.ParseIP(publicIP) == nil {
		return fmt.Errorf("codex.live-media-relay.public-ip is invalid: %q", publicIP)
	}
	if (c.UDPPortMin == 0) != (c.UDPPortMax == 0) {
		return errors.New("codex.live-media-relay UDP port minimum and maximum must both be set")
	}
	if c.UDPPortMin > c.UDPPortMax {
		return errors.New("codex.live-media-relay.udp-port-min must not exceed udp-port-max")
	}
	if c.UDPPortMin != 0 {
		availablePorts := int(c.UDPPortMax) - int(c.UDPPortMin) + 1
		requiredPorts := c.EffectiveMaxSessions() * 2
		if availablePorts < requiredPorts {
			return fmt.Errorf("codex.live-media-relay UDP range requires at least %d ports for %d sessions", requiredPorts, c.EffectiveMaxSessions())
		}
	}
	for serverIndex, server := range c.ICEServers {
		if len(server.URLs) == 0 {
			return fmt.Errorf("codex.live-media-relay.ice-servers[%d].urls is required", serverIndex)
		}
		for _, rawURL := range server.URLs {
			parsed, errParse := url.Parse(strings.TrimSpace(rawURL))
			if errParse != nil || parsed.Scheme == "" {

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Set both udp-port-min and udp-port-max (e.g. 50000 and 50100), or remove both
  2. Ensure the range has at least 2 * max-sessions ports available or validation fails with the follow-on range-size error

Example fix

# before
codex:
  live-media-relay:
    enabled: true
    udp-port-min: 50000
# after
codex:
  live-media-relay:
    enabled: true
    udp-port-min: 50000
    udp-port-max: 50100
Defensive patterns

Strategy: validation

Validate before calling

r := cfg.Codex.LiveMediaRelay
if r.Enabled && (r.UDPPortMin == 0) != (r.UDPPortMax == 0) {
    return errors.New("udp-port-min and udp-port-max must be set together")
}

Try / catch

if err := relayCfg.Validate(); err != nil {
    if strings.Contains(err.Error(), "must both be set") {
        return errors.New("config fix: set both udp-port-min and udp-port-max, or neither")
    }
    return err
}

Prevention

When it happens

Trigger: Config with enabled: true and only udp-port-min or only udp-port-max present.

Common situations: Partially filled config from documentation examples; someone sets only the lower bound expecting a half-open range.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/30e531e5454f4c2d. Report an issue: GitHub.