LiveKit connection error: ConnectionError: could n...
# ask-ai
s
LiveKit connection error: ConnectionError: could not establish signal connection: Failed to construct 'RTCPeerConnection': ICE server parsing failed: Invalid hostname format
✅ 1
t
Thanks for reaching out, Youssef. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I’m sorry you ran into that error. You’re seeing: “ConnectionError: could not establish signal connection: Failed to construct 'RTCPeerConnection': ICE server parsing failed: Invalid hostname format.” I’ll help you narrow this down and get you reconnected. What this error means • The browser failed to construct the RTCPeerConnection because one or more ICE server entries (STUN/TURN URLs) are malformed. The WebRTC layer expects properly formatted hostnames/URLs for ICE servers and will throw this error if it encounters an invalid host format. What you can check right away 1. Inspect your ICE server configuration (the
iceServers
array passed into your
RTCPeerConnection
/ LiveKit client): ◦ Each entry should be a valid URL string like
stun:stun.l.google.com:19302
or
turn:turn.example.com:3478?transport=udp
. ◦ If you use objects, ensure
urls
is present and either a string or string array: ▪︎ Valid:
{ urls: "stun:stun.example.com:3478" }
or
{ urls: ["turn:turn.example.com:3478?transport=udp"], username: "...", credential: "..." }
◦ Remove any stray characters, spaces, or missing scheme (stun/turn). Hostnames must not contain invalid characters. 1. Common mistakes to look for ◦ Leaving out the
stun:
or
turn:
scheme. ◦ Including protocol prefixes like
https://
instead of `stun:`/`turn:`. ◦ Using an IP with an extra bracket or port formatted incorrectly (e.g.,
stun:[127.0.0.1]:19302
— brackets are for IPv6). ◦ Passing a bare hostname where an URL is expected (the API expects
stun:host:port
or
stun:host
). 1. Quick test steps ◦ Temporarily remove custom ICE servers and let the client use default STUN (if applicable) to verify that the rest of your setup works. ◦ If you must use a TURN server, try a known-good TURN URL (e.g., a public STUN) to see if the error disappears — this isolates the issue to your TURN entry. If you want, I can review your config • Please paste the
iceServers
block (or the snippet where you construct the
RTCPeerConnection
/ pass rtcConfig into LiveKit) — remove any sensitive credentials before sharing. • Tell me which browser and version you’re testing in, and whether you’re using IPv6 addresses or special hostnames. If you prefer to run diagnostics first • Run a Connection Test to check WebSocket, WebRTC, and TURN reachability. The test will confirm whether the problem is malformed ICE URLs versus a network issue. Next step • Share the
iceServers
snippet (redact passwords/keys) and your browser info and I’ll point out the exact line causing the invalid-hostname parsing error and show how to fix it. Sources: Diagnosing Connection Errors with the Connection Test Utility | LiveKit | Firewall Tips for LiveKit Connectivity | LiveKit, with interactive elements
s
ERROR livekit_ffi:server:room] error while connecting to a room: engine: internal webrtc failure
t
Thanks — I’m sorry you’re hitting this. You reported two related errors: the ICE hostname parsing failure earlier and now this server-side log: ERROR livekit_ffi:server:room] error while connecting to a room: engine: internal webrtc failure I’ll help you narrow this down and recover a working session. What this “engine: internal webrtc failure” usually means • The LiveKit engine failed during WebRTC setup (SDP/ICE/DTLS stage or media engine init). It’s an internal failure in the WebRTC stack rather than a simple signaling/auth error. • Common root causes are ICE negotiation problems, malformed ICE/TURN configuration, blocked TURN/STUN connectivity, or improper rtcConfig that prevents RTCPeerConnection from being created correctly. What to check next (quick checklist) 1. ICE server entries ◦ Share the
iceServers
block you pass to the client or the rtcConfig used to create the PeerConnection (redact credentials). Invalid ICE URLs trigger earlier browser errors and can cascade to engine failures on the server. ◦ Ensure entries use
stun:
or
turn:
schemes and correct host/port formats (example:
stun:stun.example.com:19302
or
turn:turn.example.com:3478?transport=tcp
). 1. TURN reachability and network ◦ Confirm TURN is reachable from both client and server networks. If UDP is blocked, ensure you have TURN over TCP/TLS (port 443) available and that firewalls/proxies allow it. ◦ If you suspect a restrictive network, try forcing TURN by setting
iceTransportPolicy: 'relay'
temporarily. 1. Browser / platform details ◦ Tell me which browser (and version) or which SDK/platform (Node, Android, iOS) you’re using. Some platforms surface different internal errors and require platform-specific checks. 1. Server logs and timestamps ◦ Provide the full server log lines around the error (a few seconds before/after) and the timestamp. That helps identify whether this fails during offer/answer, ICE gathering, or DTLS handshake. 1. Token / project config (brief) ◦ If you recently rotated keys or changed token generation, mention it. Authentication problems usually show as auth errors, but it’s useful to rule out mismatches. Immediate steps you can try now 1. Temporarily remove custom ICE servers (or replace with a known public STUN) to see if the client can create the PeerConnection without your TURN config. 2. Run the Connection Test utility (checkWebsocket, checkWebRTC, checkTURN). This isolates whether the failure is a malformed URL vs. network blocking. 3. If using TURN, test a TURN server with TCP/TLS on 443 to bypass strict firewalls. What I need from you to go deeper • Paste the `iceServers`/rtcConfig snippet you’re using (redact passwords/keys). • Tell me: browser/SDK & version, server OS, and whether you’re using public TURN or a self-hosted TURN. • Share a short excerpt of the server log around the error (timestamps help). If you send those, I’ll examine the config for malformed hostnames or other obvious issues and suggest targeted fixes (or the exact change to make). Sources: Understanding the STATE_MISMATCH Disconnect Reason | LiveKit | client-sdk-js | livekit/livekit_composite | DeepWiki | Firewall Tips for LiveKit Connectivity | LiveKit | Diagnosing Connection Errors with the Connection Test Utility | LiveKit | Configure ZScaler proxy for LiveKit connections | LiveKit, with interactive elements
s
i am using https://docs.livekit.io/transport/self-hosting/vm/ for self hosting, i ran the script and this issue happens after a token is generated and trying to connect to it]
t
Thanks — that’s helpful context. You’re running the self‑hosted VM from the guide and the failure happens after token generation when the client tries to connect. I’ll focus on the areas most likely to cause the ICE-hostname parsing error and the “engine: internal webrtc failure” you saw. What I’ll look for and why • The browser error you saw earlier ("ICE server parsing failed: Invalid hostname format") means a malformed STUN/TURN URL is being passed to the RTCPeerConnection. • The server log "engine: internal webrtc failure" often follows ICE/SDP problems or when the engine cannot complete ICE/DTLS handshakes. In a self‑hosted VM setup, this usually traces back to incorrect rtc/ICE config or an unreachable/misconfigured TURN (coturn). Please provide these items (redact secrets like credentials or long tokens): 1. The client-side rtcConfig / iceServers snippet you pass to the LiveKit client (or the code that calls
connect()
). 2. Your LiveKit server config file (the YAML you used for the VM), specifically the
rtc.ice_servers
section. 3. Whether you enabled/use coturn in the VM (yes/no) and the coturn config if you customized it. 4. The client platform/browser and version (e.g., Chrome 115 on macOS, or JS SDK version). 5. A short excerpt of the LiveKit server logs around the error (10–20 lines before/after the timestamp). While you gather that, try these targeted checks you can do right now • Verify ICE server URL format ◦ Each ICE entry must use
stun:
or
turn:
. Examples: ▪︎ stuns/stun:
stun:stun.l.google.com:19302
▪︎ turn:
turn:turn.example.com:3478?transport=udp
or
turns:turn.example.com:443?transport=tcp
◦ Do not use
https://
or plain hostnames where the RTCPeerConnection expects `stun:`/`turn:` URLs. ◦ If your
rtc.ice_servers
uses objects, ensure they follow
{ urls: "turn:host:port", username: "...", credential: "..." }
. • Check for accidental characters or IPv6 formatting ◦ Remove stray brackets or spaces. Example invalid:
stun:[127.0.0.1]:19302
— brackets break IPv4. ◦ For IPv6 use correct bracketed format with proper scheme. • Test with a known-good STUN ◦ Temporarily replace your iceServers with a public STUN (e.g.,
stun:stun.l.google.com:19302
) to confirm the rest of the flow works. If this resolves the browser error, the issue is with your TURN/hostnames. • Confirm coturn is running and reachable ◦ On the VM, check coturn service status and that the ports you configured (UDP/TCP 3478, and 443 if using TLS) are open. ◦ If UDP is blocked in your environment, ensure you have TURN over TCP/TLS and port 443 allowed. • Try forcing relay to isolate ICE ◦ In your client rtcConfig, set
iceTransportPolicy: 'relay'
temporarily to force TURN usage. If the connection changes behavior, it indicates ICE path issues. What I’ll do once you share the snippets/logs • Inspect the
iceServers
and server YAML for malformed hostnames or missing schemes and point out the exact fix. • Highlight coturn reachability issues if logs show ICE candidates not completing. • Provide exact config lines to change (server YAML and client rtcConfig) and commands to test coturn reachability from the VM and a client machine. If you paste the
rtc.ice_servers
block from your VM config and your client
iceServers
snippet (redact credentials), plus the server log excerpt and your client/browser version, I’ll pinpoint the problem and give step‑by‑step changes to fix it. , with interactive elements
s
what is
rtc.ice_servers
i did not setup it, i only ran the script, and the client side was working with the cloud before
t
Thanks — that makes sense. I’ll explain what
rtc.ice_servers
is, why it matters for your self‑hosted VM, and the simplest next steps so we can find the malformed hostname that’s causing the WebRTC errors. What
rtc.ice_servers
is •
rtc.ice_servers
is the server-side configuration (in the LiveKit YAML) that tells LiveKit which STUN/TURN servers to advertise to clients. Those entries become the ICE server URLs passed into the browser/SDK when establishing a WebRTC PeerConnection. • Each entry must be a properly formatted STUN/TURN URL (for example:
stun:stun.l.google.com:19302
or
turn:turn.example.com:3478?transport=tcp
), or an object with
urls
,
username
, and
credential
. Why this matters for your self-hosted VM • When you ran the VM script, the setup may have populated default ICE/TURN entries or left them empty. If a malformed or empty value ended up in the generated config, the client will receive an invalid ICE URL and the browser will throw the parsing error you saw. • Cloud LiveKit likely provided valid ICE/TURN details automatically, which is why your client worked there but not with the self‑hosted VM. What to check right now (fast and safe) 1. Locate the server config file ◦ On the VM the LiveKit config usually lives in a YAML file (commonly named
livekit.yml
or similar in /etc/livekit or the directory created by the script). Open that file and look for an
rtc:
section and then
ice_servers:
underneath it. 1. Inspect the
rtc.ice_servers
block ◦ If you see entries, check they look like: ▪︎
- urls: "stun:stun.l.google.com:19302"
▪︎
- urls: "turn:turn.example.com:3478?transport=tcp", username: "user", credential: "pass"
◦ If you see anything that looks like
https://...
, an empty string, or a bare hostname without `stun:`/`turn:`, that’s the source of the parsing error. 1. If you can’t find or don’t see
rtc.ice_servers
◦ The script may have left it empty or defaulted to something invalid. That means the LiveKit server may be advertising an invalid entry or none at all, causing the client error and the server’s internal WebRTC failure. If you’re comfortable sharing (redact secrets) • Paste the
rtc.ice_servers
block from your VM’s YAML, or paste the section of the YAML around
rtc:
(you can redact usernames/credentials). • Tell me the VM OS and where you ran the script (the path to the generated config if you know it). If you prefer to check manually first, here’s a quick safe test 1. On your client, temporarily try connecting with a client-side override (no secrets needed) that uses a known-good STUN only: ◦ In the client SDK, set iceServers to:
[ { urls: "stun:stun.l.google.com:19302" } ]
◦ If connection succeeds (or the browser error disappears), the problem is definitely the server’s ICE entries. 1. On the VM, check the livekit server logs again for any lines referencing
ice_servers
or ICE candidate failures; that will confirm whether malformed entries are coming from the server. Next step I can take for you • If you paste the
rtc.ice_servers
YAML block (redact passwords/credentials), I’ll point out exactly what’s wrong and give the corrected YAML lines and a small command to reload the LiveKit service., with interactive elements
s
rtc: tcp_port: 7881 port_range_start: 50000 port_range_end: 60000 use_external_ip: true enable_loopback_candidate: false
t
Thanks — that helps. You’ve shown the
rtc:
block from your VM config and it does not include any
ice_servers
entries. That likely explains the browser error: the server is advertising either an empty/invalid ICE list or the client is receiving no valid STUN/TURN URLs, which leads to the “Invalid hostname format” and the server-side “engine: internal webrtc failure.” What to do next (short checklist) 1. Confirm the server is not providing ICE servers ◦ Check for any other LiveKit config files or environment variables the script may have created that reference
ice_servers
. If none exist, the server currently has no ICE configuration to hand to clients. 1. Quick client-side test to isolate the issue ◦ Temporarily override the client’s ICE servers so the browser receives a known-good STUN: ▪︎ Set the client SDK’s rtcConfig/iceServers to: ▪︎
{ urls: "stun:stun.l.google.com:19302" }
▪︎ If the browser error disappears or the connection proceeds further, the problem is definitely the missing/malformed server-side ICE configuration. 1. Add proper
rtc.ice_servers
to your VM config ◦ Edit your LiveKit YAML and add an
ice_servers:
block under
rtc:
. Example minimal entries: ▪︎ For just STUN: ▪︎ rtc: • tcp_port: 7881 • port_range_start: 50000 • port_range_end: 60000 • use_external_ip: true • enable_loopback_candidate: false • ice_servers: • urls: "stunstun.l.google.com19302" ▪︎ For TURN (coturn) with credentials: ▪︎ ice_servers: • urls: "turnturn.example.com3478?transport=udp" username: "TURN_USERNAME" credential: "TURN_PASSWORD" • urls: "turnsturn.example.com443?transport=tcp" username: "TURN_USERNAME" credential: "TURN_PASSWORD" • Important:
urls
must use `stun:`/`turn:`/`turns:` schemes. Do not use
http://
or
https://
or bare hostnames. 1. If using coturn bundled with the VM ◦ If you enabled coturn during setup, configure its external hostname and credentials and add the corresponding `turn`/`turns` entries to
rtc.ice_servers
. ◦ Ensure coturn is running and ports (3478 UDP/TCP, and 443/5349 if you use TLS) are accessible from clients. 1. Restart LiveKit after changing config ◦ After editing the YAML, restart the LiveKit service (or container) so it serves the updated ICE servers to clients. What I can help with next • If you paste: ◦ The client-side code where you call
connect()
(the `iceServers`/rtcConfig section if any), and ◦ The place in your VM config file where you’d like to add
ice_servers
(you can paste the YAML snippet you have now), I will: • Validate the exact YAML syntax and provide the corrected block you can paste in, and • Give the exact restart command for the VM/container and a short test to verify coturn reachability. If you prefer, start by testing the client override with the public STUN above and tell me the result — that will quickly confirm the root cause. , with interactive elements