router-for-me/CLIProxyAPI · error
codex.live-media-relay UDP range requires at least %d ports
Error message
codex.live-media-relay UDP range requires at least %d ports for %d sessions
What it means
Each media session consumes 2 UDP ports in the configured range (one per side of the relayed flow), so Validate requires at least EffectiveMaxSessions()*2 ports between udp-port-min and udp-port-max. With the default 32 sessions that is 64 ports; a narrower range fails startup with this error.
Source
Thrown at internal/config/codex_live.go:86
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 == "" {
return fmt.Errorf("codex.live-media-relay.ice-servers[%d] contains an invalid URL", serverIndex)
}
switch strings.ToLower(parsed.Scheme) {
case "stun", "stuns", "turn", "turns":
default:
return fmt.Errorf("codex.live-media-relay.ice-servers[%d] uses unsupported scheme %q", serverIndex, parsed.Scheme)
}
}
}View on GitHub (pinned to 78f0c4079e)
Solutions
- Widen the range to at least 2*maxSessions ports: for 32 sessions use >=64 ports (e.g. 50000-50099).
- Or lower max-sessions so 2*sessions fits the current range.
- Or leave both port bounds unset (0) to use the default unbounded behavior.
Example fix
# before (21 ports < 64 needed for 32 sessions) udp-port-min: 50000 udp-port-max: 50020 # after udp-port-min: 50000 udp-port-max: 50099
Defensive patterns
Strategy: validation
Validate before calling
ports := cfg.UDPPortMax - cfg.UDPPortMin + 1
if cfg.UDPPortMin != 0 && ports < cfg.EffectiveMaxSessions()*2 {
return fmt.Errorf("need >=%d UDP ports, have %d", cfg.EffectiveMaxSessions()*2, ports)
} Prevention
- Rule of thumb: allocate 2 ports per session plus headroom.
- Whenever you change max-sessions, re-check the UDP range width.
When it happens
Trigger: udp-port-min/udp-port-max are both non-zero, min<=max, but (max-min+1) < maxSessions*2 — e.g. min 50000, max 50020 (21 ports) with the default 32 sessions.
Common situations: Operators narrow the UDP range for firewall rules and forget the 2-ports-per-session requirement; raising max-sessions without widening the range.
Related errors
- codex.live-media-relay UDP port minimum and maximum must bot
- codex.live-media-relay.udp-port-min must not exceed udp-port
- codex.live-media-relay.public-ip is invalid: %q
- codex.live-media-relay.max-sessions must not be negative
- codex.live-media-relay.ice-servers[%d].urls is required
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/d1e12c784ad4dddb.
Report an issue: GitHub.