router-for-me/CLIProxyAPI · error
codex.live-media-relay.ice-servers[%d] uses unsupported sche
Error message
codex.live-media-relay.ice-servers[%d] uses unsupported scheme %q
What it means
Only the STUN/TURN scheme family is supported for ICE servers: stun, stuns, turn, turns (case-insensitive). Any other scheme — http, https, or a misspelling — fails validation with the offending scheme echoed in the message.
Source
Thrown at internal/config/codex_live.go:101
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)
}
}
}
return nil
}
View on GitHub (pinned to 78f0c4079e)
Solutions
- Change the scheme to stun/stuns/turn/turns as appropriate: 'stun:host:19302' or 'turns:host:5349'.
- For TURN over TLS use turns:, for STUN over TLS use stuns: — not https:.
- Re-run config load after the fix; the message shows exactly which scheme was rejected.
Example fix
# before urls: - https://stun.example.com:19302 # after urls: - stuns:stun.example.com:19302
Defensive patterns
Strategy: validation
Validate before calling
allowed := map[string]bool{"stun": true, "stuns": true, "turn": true, "turns": true}
for _, u := range server.URLs {
p, _ := url.Parse(strings.TrimSpace(u))
if !allowed[strings.ToLower(p.Scheme)] {
return fmt.Errorf("unsupported scheme %q", p.Scheme)
}
} Type guard
func isSupportedICEScheme(raw string) bool {
p, err := url.Parse(strings.TrimSpace(raw))
if err != nil { return false }
switch strings.ToLower(p.Scheme) {
case "stun", "stuns", "turn", "turns":
return true
}
return false
} Prevention
- Memorize the allowed set: stun/stuns/turn/turns; https:// is never valid here.
- The error message echoes the rejected scheme — use it to locate the bad entry.
When it happens
Trigger: Validate's switch on strings.ToLower(parsed.Scheme) hits default — e.g. 'https://stun.example.com' used because it looked like a normal web endpoint, or 'stun:' fat-fingered as 'stunN:'.
Common situations: Users wrap the STUN host in https:// out of habit; tooling templates prepend https://; typo'd scheme after editing.
Related errors
- codex.live-media-relay.ice-servers[%d].urls is required
- codex.live-media-relay.ice-servers[%d] contains an invalid U
- codex.live-media-relay.public-ip is invalid: %q
- codex.live-media-relay UDP range requires at least %d ports
- codex.live-media-relay.max-sessions must not be negative
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/e1554352e68c434d.
Report an issue: GitHub.