steep-balloon-41261
02/14/2026, 7:06 AMtall-airline-16756
02/14/2026, 7:06 AMtall-airline-16756
02/14/2026, 7:06 AMwait_pc_connection timed out error when using @livekit/rtc-node (your logs show signaling succeeded but the WebRTC peer connection never completed).
Below are the most likely causes and focused steps you can try to resolve it.
Key cause summary
• The error means signaling/join succeeded, but ICE/DTLS (the actual media peer connection) failed to complete within the timeout. This is typically a network/ICE issue (blocked ports, NAT, missing TURN, wrong public IP), or an environment incompatibility with the Node WebRTC stack.
Quick checks to run now
• Are you testing against a server reachable only at 127.0.0.1 from the client machine? If the server is local but the client is remote, ICE candidates may be private addresses and won’t be reachable.
• Can the machine running rtc-node reach the LiveKit server’s media ports (UDP range) and TURN/STUN servers? Verify basic connectivity (ping/traceroute/tcping) to the server host and TURN host.
Practical troubleshooting steps 1) Force relay (TURN) to confirm ICE reachability
• Try forcing the client to use TURN (relay) so you can determine if UDP pathing is the problem:
const room = new Room();
await room.connect(url, token, {
rtcConfig: { iceTransportPolicy: 'relay' }
});
• If that connects, the problem is UDP/NAT/ICE — proceed to configure/allow TURN.
2) Verify TURN/STUN configuration on the LiveKit server
• Ensure your LiveKit server is configured with reachable STUN/TURN servers and that credentials are valid.
• If your TURN server is behind firewalls, make sure ports (TCP/UDP 3478, 5349 and any TURN media ports like 443) are open.
3) Ensure the server advertises a public IP/domain
• If server binds only to localhost/private IP, remote peers won’t be able to reach the media address. Set the LiveKit server to bind to the public interface and set public_ip (or equivalent) so correct ICE candidates are advertised.
4) Open firewall / forward UDP media ports
• Media uses UDP ephemeral ports (commonly 10000–20000). Make sure those are allowed/forwarded on the server side and not blocked on your network.
5) Compare CLI vs rtc-node ICE candidates
• The CLI may succeed by using different ICE candidates or fallbacks. In rtc-node you can log the SDP/offers/answers to inspect what candidates are being exchanged and confirm whether host/public/relay candidates appear.
6) Node.js / rtc-node environment differences
• rtc-node uses the WebRTC native implementation; behavior differs from the CLI. Try a known stable Node version (e.g., Node 18 or 20) instead of experimental versions that might break native modules.
• Ensure system libs required by the native WebRTC bindings are present.
7) Collect server logs and look for handshake failures
• On the server side, search for ICE/DTLS related messages such as “ICE connection failed”, “DTLS handshake timeout”, or “no candidate pair available”. Those messages confirm where the handshake is failing.
If you want, I can help next with one of these targeted steps:
• Walk through forcing TURN and configuring TURN credentials in your LiveKit server.
• Show how to log/inspect the SDP candidates exchanged by rtc-node.
• Review specific server logs if you paste the ICE/DTLS related lines (redact secrets).
Which one would you like to try first?
Sources: Firewall Tips for LiveKit Connectivity | LiveKit | Diagnosing Connection Errors with the Connection Test Utility | LiveKit | client-sdk-js | livekit/livekit_composite | DeepWikibreezy-accountant-5907
02/14/2026, 7:07 AMtall-airline-16756
02/14/2026, 7:08 AMwait_pc_connection timed out problem with @livekit/rtc-node.
What the logs show
• The server accepts the client’s signaling/join request (you see "starting RTC session" with Client: NODE v0.13.24). That means token and WebSocket signaling succeed.
• The participant is then removed “without connection” with reasons like SIGNAL_SOURCE_CLOSE and DUPLICATE_IDENTITY. That indicates the rtc-node client never completed the ICE/DTLS media handshake and the client closed the signaling channel (the sdk’s internal timeout was reached).
• This confirms the failure point is the WebRTC media path (ICE/TURN), not authentication/signaling.
Concrete next steps to isolate and fix the problem 1) Force TURN to confirm it’s an ICE/UDP issue
• In your rtc-node client, force relay-only so all media goes via TURN:
await room.connect(url, token, {
rtcConfig: { iceTransportPolicy: 'relay' }
});
• If that succeeds, UDP/peer-to-peer connectivity is blocked and you need TURN for production.
2) Check TURN/STUN reachability and config
• Verify the LiveKit server has correct TURN/STUN URIs and credentials configured and that the TURN server is reachable from the rtc-node host.
• Ensure TURN ports are open (TCP 443 or TCP/UDP 3478 as applicable) and any relay ports are available.
3) Verify server public IP / advertised candidates
• If your LiveKit server runs behind NAT or bound to private interfaces (127.0.0.1), make sure it advertises its public IP or hostname so correct ICE candidates are sent to clients.
4) Open/forward UDP media ports on server
• WebRTC commonly uses UDP ephemeral ports (often configured 10000–20000). Confirm host/network firewalls allow inbound/return UDP on those ports or that TURN covers the path.
5) Compare CLI vs rtc-node behavior
• The CLI may use different ICE candidates/fallbacks. Capture and compare the SDP/candidates from:
◦ rtc-node: log offers/answers or inspect signal events
◦ CLI: see which candidates it uses
• If CLI succeeds but rtc-node fails on the same host/network, check for environment differences (Node version, required native libs).
6) Address duplicate identity messages (if relevant)
• Your logs show a DUPLICATE_IDENTITY removal; that happens when a second participant tries to join with the same identity. If your bot reconnects quickly, ensure your client handles reconnection correctly (reuse same participant connection or wait for previous session to close) so duplicate identity removal doesn't interfere with ICE setup.
If you want, I can help with any of these specific actions:
• Walk through forcing TURN and verifying TURN config on your LiveKit server.
• Show how to log/inspect the rtc-node SDP offers/answers and ICE candidates.
• Help interpret server logs you paste that show ICE/DTLS failure messages (e.g., “ICE connection failed”, “DTLS handshake timeout”).
Which of the above would you like to try first?
Sources: Understanding the STATE_MISMATCH Disconnect Reason | LiveKit | Firewall Tips for LiveKit Connectivity | LiveKit | Diagnosing Connection Errors with the Connection Test Utility | LiveKittall-airline-16756
02/14/2026, 7:11 AMnode_ip you set), or is it behind NAT/load‑balancer? Is use_external_ip intentionally false because you set node_ip manually?
2) TURN/STUN setup
• Are you using an external TURN server, or relying on an embedded TURN? If external, please confirm the TURN URI, protocol (tcp/tls/udp), and port (redact credentials).
• Do clients have network access to that TURN server (try curl/tcping from the rtc-node host to the TURN host/port)?
3) Ports & firewalls
• Are the UDP port range 50000–60000 open and forwarded to the LiveKit node from your cloud firewall / datacenter network? Is tcp_port: 7881 exposed (if you expect TCP ICE fallback)?
• Is there any host-level firewall (iptables/nftables, cloud security group) that might block UDP?
4) Where rtc-node runs vs CLI
• Where did you run the LiveKit CLI that succeeded (same host as rtc-node app, or different machine)? If different, can you run the CLI from the same host/container where your rtc-node process runs to compare behavior?
5) Node runtime / native dependencies
• Which Node.js version does your rtc-node app use in production? (You previously mentioned v25.6.1 — is that still what rtc-node runs on?)
6) Duplicate identity / reconnect behavior
• Logs show DUPLICATE_IDENTITY at times. Is your bot or test client reconnecting repeatedly with the same identity? If so, are you intentionally creating multiple simultaneous connections with the same identity, or should the client be reusing a prior session?
Immediate checks you can run now
• Force TURN in rtc-node to test connectivity:
await room.connect(url, token, {
rtcConfig: { iceTransportPolicy: 'relay' }
});
If this succeeds, the issue is blocked UDP/ICE and you must ensure TURN is configured and reachable.
• From the rtc-node host, test connectivity to STUN/TURN:
◦ Try connecting to the TURN port (e.g., tcping or curl to TCP 443 if TURN over TLS).
◦ If you have access, run a packet capture (tcpdump) on the LiveKit node for UDP ports 50000–60000 while attempting a connection to see if ICE packets arrive.
• Check the server’s advertised candidates: set use_external_ip: true or ensure node_ip is the correct public IP for that node so clients receive reachable candidates.
What I can help with next
• If you answer the 6 questions above, I’ll give a step-by-step plan (TURN config, firewall rules, and small config edits) tailored to your setup.
• If you prefer, I can walk you through how to capture and paste the relevant ICE/DTLS failure lines from server logs or how to log the rtc-node SDP/ICE candidates for comparison.
Which of the above would you like to do first — run the TURN-forcing test, or confirm the node IP / firewall/TURN details?breezy-accountant-5907
02/14/2026, 7:12 AMtall-airline-16756
02/14/2026, 7:12 AMiceTransportPolicy eklediniz fakat TURN kurulumunda “sertifika” sorunu olduğu için devam edemediniz. Bu durumda iki yönlü kısa rehber veriyorum: (A) hızlı test için geçici çözümler, (B) production için doğru TURN + TLS yapılandırması ve sertifika adımları. Hangisini tercih ettiğinizi söyleyin, sonra adım adım devam edelim.
A — Hızlı test / geçici çözümler
• iceTransportPolicy: 'relay' ekleyip yine bağlantı kuramıyorsanız TURN sunucunuza erişim veya sertifika problemi halen engel oluyor. Yine de bağlantının TURN ile çalışıp çalışmadığını doğrulamak için:
a. TURN sunucusunun adresine (örn. turn.example.com) TCP 443 ile erişilebildiğini test edin (aynı makineden):
• Basitçe: curl -v <https://turn.example.com:443> (TLS el sıkışması görmeniz gerekir; TURN protokolünü anlamaz ama port açık mı kontrolü sağlar).
a. Eğer TURN yoksa, lokal test için aynı ağda (aynı LAN) client ve server çalıştırarak UDP doğrudan bağlantısını test edin — bu, ağ/port engeli olup olmadığını ayırır.
B — TURN + TLS (sertifika) kurulum adımları (özet)
• Neden TLS gerekiyor: Modern tarayıcılar ve pek çok ağ güvenlik kuralı TURN üzerinden TCP/TLS (443) isteklerini tercih eder. Eğer TURN sunucunuz TLS istemiyorsa veya sertifika hatalıysa bağlantılar reddedilir.
Adımlar: 1) Alan adı ve sertifika
• TURN sunucusu için bir alan adı (FQDN) kullanın. IP ile TLS hataları çıkabilir.
• Üretimde en kolay yol: Let’s Encrypt ile gerçek sertifika almak (ücretsiz). Eğer test ortamıysa self-signed kullanabilirsiniz ama tarayıcılar/istemciler hata verir; rtc-node tarafında da ek konfig gerekebilir.
• Let’s Encrypt kullanmak için sunucunuzun 80/443 portları erişilebilir olmalı. Certbot ile otomatik alınır.
2) TURN sunucusu (coturn) temel yapılandırma
• Örnek /etc/turnserver.conf (TLS ile):
◦ listening-port=3478
◦ tls-listening-port=5349
◦ external-ip=<PUBLIC_IP>
◦ fingerprint
◦ use-auth-secret
◦ static-auth-secret=<strong-password>
◦ realm=<your-domain>
◦ cert=/etc/letsencrypt/live/your-domain/fullchain.pem
◦ pkey=/etc/letsencrypt/live/your-domain/privkey.pem
◦ no-stdout-log
◦ total-quota, bps-capacity vb. (opsiyonel)
• TLS için cert ve pkey yolları Let’s Encrypt sertifikanızın gerçek yolları olmalı.
3) LiveKit server yapılandırması
• LiveKit config içinde TURN bilgilerini belirtin (TURN URI, kullanıcı/secret ya da username/password).
• Örnek: turn:turn.example.com:3478?transport=udp veya turns:turn.example.com:5349?transport=tcp
• Eğer use_auth_secret ile coturn yapılandırdıysanız, LiveKit tarafında turn kullanıcı bilgilerini doğru şekilde besleyin.
4) Firewall / portlar
• TURN (UDP 3478 ve TCP 5349/443) ve TF sürümlerine göre açın.
• Media için LiveKit node üzerinde UDP ephemeral port aralığını açın (örn. 10000–20000).
Alternatifler (eğer sertifika almak şu an mümkün değil)
• Geçici olarak:
◦ Aynı ağ içinde test yapın (aynı LAN/VM host) — bu durumda TURN gerekmez.
◦ Self-signed sertifika kullanabilirsiniz; rtc-node tarafında self-signed TLS’ı kabul etmek için ek ayar/işlem gerekebilir (ve güvenlik riskleri vardır).
• Eğer cloud sağlayıcınız varsa çoğu sağlayıcı (Cloudflare, AWS, GCP) SSL/TLS terminasyon ve/veya managed TURN benzeri hizmet sunabiliyor — bunları değerlendirebilirsiniz.
Ek bilgiler / Benimle paylaşabilecekleriniz
• TURN kurmayı tercih eder misiniz yoksa önce aynı LAN’da test mi yapmak istersiniz?
• Eğer TURN kuracaksanız: kullanmak istediğiniz alan adı (veya public IP), coturn mu yoksa başka bir TURN mı tercih ediyorsunuz?
• Let’s Encrypt ile sertifika almaya uygun bir domain mevcut mu?
• rtc-node uygulamanızı hangi Node sürümünde çalıştırıyorsunuz (daha önce v25 belirtmiştiniz)?
İsterseniz şimdi adım adım: 1) Eğer domain ve 80/443 açıksa Let’s Encrypt ile coturn sertifikası alma ve coturn.conf örneği veririm. 2) Ya da önce iceTransportPolicy: 'relay' ile denedikten sonra curl/tcping çıktılarınızı paylaşırsınız; birlikte kontrol ederiz.
Hangi yolu tercih ediyorsunuz?breezy-accountant-5907
02/14/2026, 7:13 AMtall-airline-16756
02/14/2026, 7:13 AMroom.on('signal', msg => console.log(msg)) benzeri bir yakalama ile SDP/ICE mesajlarını alın.
2) Paket yakalama (aynı makinede)
• Deneme sırasında server ve client makinelerinde udp portları için tcpdump çalıştırın (ör. 10000–20000 aralığı).
• Amaç: ICE paketleri gerçekten gidip geliyor mu, yoksa hiç UDP paketi gelmiyor mu görmek.
• Örnek: sudo tcpdump -n -i eth0 udp and portrange 10000-20000
3) Host binding / advertised IP kontrolü
• LiveKit sunucunuzun node_ip veya public_ip ayarları doğru mu? Eğer sunucu kendini 127.0.0.1 veya iç IP ile ilan ediyorsa aynı LAN’da bile paket rotası bozulabilir.
• Konfigda node’un hangi IP’yi advertise ettiğini (server loglarında görünen candidate IP’leri) kontrol edin.
4) localhost vs LAN test farkı
• Client ve server aynı fiziksel makine üzerinde ise (localhost/127.0.0.1), deneyin: hem server hem client aynı hostta çalıştırıp bağlanıyor mu?
• Ardından aynı LAN’daki farklı makineler (aynı switch/router) ile test edin. Bu adımın amacı host- ve ağ-özel farkları görmek.
5) Firewall / host güvenlik yazılımı
• Hem client hem server makinelerinde OS firewall (iptables/nftables/ufw, Windows Defender vb.) kapatıp deneyin kısa süreli test için.
• Bazı sistemlerde outbound UDP kısıtlı olabilir; bütün yönleri geçici olarak açık hale getirip tekrar deneyin.
6) Node / rtc-node native bağımlılıkları ve sürüm
• Hangi Node.js sürümü kullanıyorsunuz? rtc-node native WebRTC binding’leri bazı Node sürümlerinde sorun çıkarabilir. Daha stabil olan Node 18 veya Node 20 ile deneyin.
• rtc-node sürümü ile server sürümünün uyumluluğunu kontrol edin (SDK 0.13.24 görünüyor).
7) Duplicate identity / reconnect davranışı
• Loglarda DUPLICATE_IDENTITY mesajları var; test sırasında aynı identity ile hızlı tekrar bağlantı denemeleri oluyor mu? Bu, eski oturum temizlenmeden yeni oturum açılmasına ve beklenmeyen kapanmalara yol açabilir. Testler sırasında tek katılımcı/tek identity kullanın.
Hedefe yönelik ilk iki öneri (en hızlı sonuç üretecek) 1) SDP/ICE adaylarını logla ve paylaş
• Bunu yapınca adaylarda sadece host mı yoksa `srflx`/`relay` de mi olduğunu göreceğiz. Host-only adaylar NAT/firewall problemi işaret eder.
2) Basit paket yakalama
• İki makinede tcpdump ile bağlantı denenirken UDP paketleri gelip gelmediğini kontrol et. Eğer hiçbir UDP paket gelmiyorsa problem yerel firewall/OS ağ yönlendirmesinde demektir.
Bana şu bilgileri paylaşırsanız daha doğrudan çözüm verebilirim
• rtc-node uygulamanızın çalıştığı işletim sistemi, Node sürümü.
• Server’ın LiveKit node olarak hangi IP’yi advertise ettiğinin çıktısı (ya da rtc-node tarafından görülen SDP’deki candidate’lardan birkaç örnek — IP’leri sansürleyebilirsiniz).
• Paket yakalama çıktısında UDP trafiğinin gözüküp gözükmediği (kısa tcpdump çıktısı).
• Testleri yaparken aynı kimlikle (identity) tekrar bağlanma yapıp yapmadığınız.
İsterseniz önce SDP/ICE adaylarını nasıl loglayacağınızı gösteririm ve hemen ardından tcpdump komutlarını veririm. Hangi adımla başlamak istersiniz?breezy-accountant-5907
02/14/2026, 7:16 AMtall-airline-16756
02/14/2026, 7:16 AMroom.on('signal', (msg) => console.log('signal:', msg));
room.on('connectionStateChanged', (s) => console.log('conn state:', s));
// and log offer/answer SDPs and candidate lines when received
• Also enable debug env if supported (check rtc-node docs) so native WebRTC stack logs appear. Share the candidate lines you see (you can redact IPs).
5) Try a more stable Node runtime
• Node v25 is experimental and can cause native addon issues. Try running your rtc-node app with Node 18 or 20 and repeat the test. If the native WebRTC binding fails silently on v25, it may not open UDP sockets.
6) Quick browser client check
• From any machine on the same LAN as your rtc-node host, open a simple browser-based LiveKit client and connect to the same room. Browsers often have clearer fallbacks and easier debugging — if the browser also fails to establish ICE (and tcpdump still sees no UDP), it confirms network blocking rather than rtc-node-specific issues.
7) Check server advertised candidates in SDP
• Capture the SDP the server sends back and verify the candidate types: host, srflx, relay. If the server only advertises host and it’s not reachable, that can still fail on same LAN if the IPs are incorrect. Paste a few candidate lines (redact IPs) and I’ll examine them.
If you prefer a concrete next action, do this now and paste the results:
1. Temporarily disable ufw on the rtc-node host (sudo ufw disable), rerun tcpdump, attempt connect, and paste whether you now see UDP packets.
2. If you prefer not to disable firewall, run the UDP netcat test from step 2 and paste whether packets arrive.
If you run into anything you’re unsure about, tell me which step you did and the exact output — I’ll interpret it and tell you the precise fix.breezy-accountant-5907
02/14/2026, 7:18 AMtall-airline-16756
02/14/2026, 7:19 AMsignal ve ICE olaylarını loglamak bize adayların (candidates) tipini gösterecek:
room.on('signal', (msg) => console.log('signal:', JSON.stringify(msg)));
room.on('connectionStateChanged', (s) => console.log('conn state:', s));
• Paylaşman gereken: signal mesajlarında görünen ICE adaylarından birkaç satır (candidate=... içeren bölümü). IP’leri sansürleyebilirsin.
• Eğer hiç candidate gözükmüyorsa, rtc-node ICE toplama yapmıyor demektir (runtime/native problem).
6) Alternatif hızlı kontrol — browser istemci ile test
• Aynı LAN’daki bir bilgisayarda tarayıcı ile LiveKit demo/örnek bağlantısı kurmayı dene. Browser da UDP paketleri gönderip tcpdump üzerinde görünüyor mu kontrol et. Eğer tarayıcıdan da paket gelmiyorsa kesinlikle ağ/host düzeyinde bir engel var.
Hangi çıktıları paylaşmalısın (bana gönder)
• Netcat testinin tam çıktısı: hem sunucu tarafında (nc -u -l) hem istemci tarafında (nc komutunun çıktısı).
• sudo iptables -L -n -v ve sudo ufw status verbose çıktıları.
• Eğer Node sürümünü değiştirip denersen: Node sürümü ve tcpdump sonucu (yoksa “yine yok” diye belirt).
• rtc-node’den aldığın signal mesajlarındaki ICE candidate satırlarından 2-3 örnek (IP’leri sansürle).
Kısa yol önerisi (en hızlı teyit için)
• Hemen şimdi yapabileceğin en hızlı iki test:
1) Netcat UDP testini hem yönde çalıştır (server dinle, client gönder) ve sonucu yaz. 2) Node sürümünü 18’e indirip uygulamayı çalıştır, tcpdump yeniden başlat, tekrar dene. Sonuçları paylaş.
Benimle hangi testi yaptığını ve çıktılarını paylaşırsan bir sonraki adımı doğrudan söyleyeceğim (ör. iptables kuralı ekleme, cloud security rule örneği, veya rtc-node rebuild önerisi). Hangi testi şimdi yapıyorsun?breezy-accountant-5907
02/14/2026, 7:19 AMtall-airline-16756
02/14/2026, 7:20 AMnpm install yap.
3) rtc-node paketinin kurulum ve runtime hatalarını yakala
• npm install sırasında çıkan hataları kontrol et; özellikle native addon derleme/uprade uyarıları varsa kopyala.
• Uygulamayı başlatırken stdout/stderr’i kaydet:
node yourApp.js 2>&1 | tee run.log
• Eğer native modül yükleme başarısızsa burada hata görünür.
4) RTC-NODE debug/ICE logging’i aç
• Uygulamada signal/connection event’lerini logla. Örnek:
room.on('signal', (msg) => console.log('signal:', JSON.stringify(msg)));
room.on('connectionStateChanged', (s) => console.log('conn state:', s));
room.on('iceCandidate', (c) => console.log('ice candidate:', c));
• Eğer iceCandidate veya signal içinde candidate= satırı yoksa rtc-node ICE toplama yapmıyor demektir.
5) Eğer hala candidate yoksa — package rebuild / reinstall deneyin
• node-gyp/rebuild ile native modülü yeniden derle:
npm rebuild @livekit/rtc-node --build-from-source
• Ya da tamamen silip yeniden kur:
npm uninstall @livekit/rtc-node npm install @livekit/rtc-node
6) Alternatif doğrulama: Minimal örnek çalıştır
• Sıfırdan küçük bir test dosyası ile sadece room.connect yap ve tüm signal mesajlarını bas:
◦ Bu, kendi uygulama mantığının üstündeki bir sorun olup olmadığını ayırır.
7) Eğer native hata veya izin/sistem sorunu çıkarsa paylaş
• npm install / rebuild çıktılarını paylaş (hataları kopyala, gizli anahtar yoksa logu olduğu gibi paylaşabilirsin).
• run.log içindeki başlangıç hatalarını paylaş.
Eğer yukarıdaki adımlardan sonra candidate görünür hale gelirse:
• tcpdump ile tekrar kontrol et; artık UDP paketleri geliyorsa ICE başlayacaktır.
• Eğer candidate’lar çıkıyor ama yine UDP yoksa ağ/iptables/security group adımlarına geri döneriz.
Hızlı test önerisi — şu an ne yapalım?
• Hemen önce: Node’u 18 yapıp npm install ile yeniden kurar mısın, sonra uygulamayı başlatıp signal/ice log çıktısını paylaşır mısın?
• Eğer istersen `npm install`/`npm rebuild` çıktısını buraya yapıştır; ben çıktılarda native addon hatalarını arayıp yönlendireyim.
Senin için sıradaki en etkili adım Node sürümünü 18’e almak ve yeniden kurmak olacaktır. Dilersen adımların komutlarını yine baştan veririm ve çıktıları nasıl paylaşacağını söylerim. Hangi adımla başlamak istersin?breezy-accountant-5907
02/14/2026, 7:22 AMtall-airline-16756
02/14/2026, 7:22 AM@livekit/rtc-node never initializes or cannot create sockets on your host — so it never gathers candidates. Let’s focus on deeper runtime/native diagnostics and a reproducible minimal test to identify the failure.
Next focused checks (do these in order)
1) Capture runtime stderr/stdout for native initialization errors
• Start your app and capture logs to a file:
node yourApp.js > run.log 2>&1
• Reproduce a connection attempt, then paste the tail of run.log (last ~200 lines). Look for errors referencing native modules, libwebrtc, dlopen, symbol errors, or permission/EPERM errors.
2) Check that the native addon is loaded
• In Node REPL or a tiny script, require the rtc-node module and log if it loads:
try {
const rtc = require('@livekit/rtc-node');
console.log('rtc-node loaded', Object.keys(rtc));
} catch (e) {
console.error('failed to load rtc-node:', e);
}
• Run that script under Node 18 and paste the output/error.
3) Rebuild with verbose output and watch for errors
• Run:
npm rebuild @livekit/rtc-node --build-from-source 2>&1 | tee rebuild.log
• Inspect rebuild.log for build/link errors or missing libraries. Paste any errors you see.
4) Ensure required system libraries are installed (Ubuntu 22)
• Install libraries commonly needed by native WebRTC bindings:
sudo apt update sudo apt install -y build-essential pkg-config libssl-dev ca-certificates \ libasound2 libpulse0 libudev1 libx11-6 libxrandr2 libxss1 \ libxtst6 libpci3 libglib2.0-0 libnss3 libgbm1
• After installing, remove node_modules and reinstall:
rm -rf node_modules package-lock.json npm install
5) Run a minimal repro that only attempts connect and logs signals
• Create test.js:
const { Room } = require('@livekit/rtc-node');
(async () => {
const room = new Room();
room.on('signal', (msg) => console.log('signal:', JSON.stringify(msg)));
room.on('connectionStateChanged', (s) => console.log('conn state:', s));
try {
await room.connect(process.env.LK_URL, process.env.LK_TOKEN);
console.log('connected');
} catch (e) {
console.error('connect failed:', e);
}
})();
• Run with environment variables set and capture output:
LK_URL=... LK_TOKEN=... node test.js > test.log 2>&1
• Paste the test.log tail (redact token).
6) If rtc-node loads but still no candidates, check permission/SELinux/container issues
• Are you running inside a container (Docker) or with AppArmor/SELinux enabled? Some container runtimes restrict raw sockets or UDP behavior.
• If Docker: ensure the container has NET_ADMIN or the network mode is host for tests:
docker run --network host ...
• If running as non-root, try running as root for a quick test.
7) Try a prebuilt example from LiveKit repo / official example
• Clone the JS examples and run their Node native example to see if candidates appear:
git clone https://github.com/livekit/client-sdk-js cd client-sdk-js/examples/node npm install
follow example README to run with your URL/token
What to share next (paste these outputs)
• Output of the tiny require test (step 2).
• Tail of run.log or rebuild.log showing native errors (steps 1 & 3).
• test.log from the minimal repro (step 5).
• Tell me whether you run in Docker or bare VM, and whether you can try host networking or run as root temporarily.
If you prefer, I can give the exact commands to run each step and explain how to redact sensitive lines. Which step would you like to run first?