This message was deleted.
# ask-ai
s
This message was deleted.
t
Thanks for reaching out, G.. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I can see the agent started, registered with LiveKit Cloud (Germany 2), and is reporting repeated "process memory usage is high" warnings, but you can't connect in production while it works locally. I’ll help you narrow this down. Quick summary of what the logs tell us • Agent started and registered: "registered worker" and server_info show Cloud (Germany 2). • Health endpoint bound: "Server is listening on port 8081". • Repeated memory warnings (~528–551 MB) with memoryWarnMB at 500. This can make a worker slow or unresponsive even if it stays registered. What to check next (step-by-step) 1. Confirm dispatch rules ◦ Verify you have an active dispatch rule or that your room creation includes agent dispatch (agent grant or
agents: [{ agentName: "your-agent-name" }]
). If no dispatch, the worker will never be sent jobs even though it’s registered. 1. Check Agent Insights / session traces ◦ Open the Agent Insights or the session trace for the room attempt and look for dispatch attempts, timeouts, or errors when assigning a job to the worker. 1. Verify agent name & availability ◦ Ensure the agent name in your deployment matches the dispatch target. Your logs show one worker registered, but confirm it’s the correct
agent_name
. 1. Confirm client-side connectivity ◦ Run the LiveKit Connection Test: ▪︎ WebSocket, WebRTC, and TURN checks. ◦ If any test fails, the problem is client network/firewall related (not the agent itself). 1. Look for client error messages ◦ When connecting the client, capture the exact client-side error (browser console logs or SDK error). Examples to share: ICE failures, TURN errors, or signaling/WS connection errors. 1. Network / firewall / proxy issues ◦ Production environments often have different egress/ingress rules. Check for: ▪︎ Blocked ports (WebRTC/UDP, TURN) ▪︎ Corporate proxies / DPI (ZScaler can block WebRTC) — if present, try bypass rules for LiveKit domains. 1. Address the memory warnings ◦ High memory usage can cause the worker to not accept or process jobs reliably. Consider: ▪︎ Reducing concurrency per instance ▪︎ Deploying an additional worker for HA ▪︎ Deploying a minimal agent build to test whether memory usage is the cause What I need from you to continue troubleshooting • The dispatch method you use (token-based agent grant, room configuration, or other). • Any client-side error text (browser console or SDK logs) when trying to connect. • Whether the agent name in your deployment matches the name used in dispatch. • Whether you’ve tested connectivity with the LiveKit Connection Test and the results. If you share the client error and dispatch method, I’ll suggest targeted checks and next steps (e.g., sample token payload to verify agent grant, what to look for in Agent Insights, or network rules to open). Sources: Voice AI quickstart | LiveKit Documentation | server-sdk-go | livekit/livekit_composite | DeepWiki | Diagnosing Connection Errors with the Connection Test Utility | LiveKit | Configure ZScaler proxy for LiveKit connections | LiveKit | Streamline troubleshooting with Agent Observability
Thanks — understood. I’ll be direct and action-focused. You said agent name is correct, transcription works (so agent is processing audio), but you can’t connect to the room in production while the same agent works locally. That narrows this to a client-side signaling/ICE/connectivity problem or a dispatch/room join mismatch in production. Please provide these three quick items so I can pinpoint the cause and give an immediate fix: 1. Exact client-side error or SDK log when attempting to join the room (copy/paste the browser console or server SDK error). Examples I’m looking for: ICE failure, WebSocket/signal disconnect, TURN auth error, or "could not join room" messages. 2. How you dispatch the agent to the room (choose one): ◦ token grant with
agent: true
or an
agents
field in the room payload (paste the token payload or room creation snippet), or ◦ another dispatch method (name it). 1. Result of the LiveKit Connection Test (if you ran it): which checks failed — WebSocket, WebRTC, or TURN? If you can’t copy logs, tell me whether: • The client establishes a WebSocket/signaling connection (sign of signaling working), or • The client fails immediately with ICE/TURN errors (sign of NAT/firewall). With those three items I’ll give the exact next steps (token snippet to check, what to change in network rules, or a minimal test to isolate the issue).
Thanks — this is very helpful. You’ve shown the token/roomConfig with agent dispatch and the WebRTC logs. You also confirmed transcription works, which means the agent is receiving audio and processing it. That lets us be targeted: the agent and dispatch are working, but the client-side join path (signaling/ICE/TURN) in production is failing. Here are the most likely causes and immediate checks to run — direct, no fluff. 1) Confirm signaling connection • Check browser/device console for any WebSocket or HTTP errors when you attempt to join (e.g., failed WebSocket, 401/403 from the LiveKit endpoint, or "signal disconnected"). If you see those, the client is failing to reach the LiveKit signaling endpoint. • If possible, paste the exact signaling error. That immediately points to token/auth or endpoint issues. 2) Check ICE/ICE-gathering & TURN • From your rn-webrtc logs, SDP offer/answer and addIceCandidate steps appear; you also get ontrack. But that can still succeed locally and fail in production because of NAT/firewall/TURN. • Run the LiveKit Connection Test (WebSocket, WebRTC, TURN). If TURN fails or ICE never completes, the clients won’t form media paths. • If ICE fails, ensure your production clients can reach TURN servers and UDP is allowed (or TCP TURN fallback is available). Corporate proxies/DPI (ZScaler) commonly block or rewrite traffic. 3) Verify the client actually completes join after signaling • The logs show setRemoteDescription and ontrack — these are normal during negotiation. Confirm the client receives a successful "joined" event from the LiveKit SDK (or no error is thrown by join). If the client never emits join success, capture that SDK event/error. • Share the SDK join result/error if you have it. 4) Double-check token / room name / grants in production • Your token snippet looks correct (room grant + roomConfig agents). Confirm the token used by the client is the generated one (not a stale token). A 401/permission error will show in signaling logs. • Confirm the roomName exactly matches (case-sensitive). 5) Edge case: Agent processes audio but is not in-room participant • Transcription working shows the agent receives audio data, which could be via a different path (e.g., server-side ingestion). Confirm the agent also joins as a participant in the same room (Agent Insights or session trace). If the agent is receiving audio via an out-of-band path, clients might still fail to join. 6) Memory warnings may cause intermittent failures • Your earlier logs showed repeated "process memory usage is high". That can cause timeouts or failed job acceptance under load. Try deploying a fresh minimal worker (less memory usage) to rule out resource-induced failures. Concrete immediate actions I recommend (in order) 1. Capture and paste the exact client-side SDK error or signaling error when joining. This is the fastest path to root cause. 2. Run the LiveKit Connection Test from a failing client network and tell me which checks fail (WebSocket/WebRTC/TURN). 3. Confirm client receives a SDK "joined" success event or paste the join call stack/response. 4. If ICE/TURN fails, try forcing TURN TCP port to validate blocked UDP — show me Connection Test TURN result. 5. If you can, deploy a minimal agent instance (or restart the agent) to rule out memory as the cause. If you give me item (1) — the exact client error — I will give the exact one-line fix (token, network rule, or TURN change).
Thanks — I get it. You want a direct answer: why it works locally but not in production. Short answer • Your production agent is registered and processing audio (transcription), but clients cannot fully join the room because the client-side signaling/ICE/TURN path is failing in production. The most likely cause is network/firewall/proxy blocking WebSocket or TURN connectivity from your production environment or the client networks. Memory warnings on the agent can make things flaky but are not the primary reason you see transcription (which means audio reaches the agent). What to check right now (fast, do these in order) 1. Grab the exact client-side error ◦ Paste the browser/React Native console error you see when the join fails (ICE failures, WebSocket disconnect, 401/403, TURN auth, or "could not join room"). This is the single most useful piece of info. 1. Run the LiveKit Connection Test from the failing client/network ◦ Tell me which checks fail: WebSocket, WebRTC, or TURN. If TURN or ICE fails, you have a NAT/firewall issue. 1. From the production host (where the agent runs) test outbound connectivity ◦ Confirm outbound WSS (port 443) to LiveKit is allowed: ▪︎ Try to open a wss connection or use a simple websocket client to your LiveKit URL. ◦ Ensure connectivity to TURN servers (turn.livekit.cloud) on port 443 (TLS) is allowed. 1. Confirm client actually receives a "joined" event ◦ Does the SDK emit a successful join event? If not, capture and paste the event/error. Quick checks and fixes to try immediately • Whitelist these outbound destinations in your firewall/proxy: ◦ *.livekit.cloud ◦ *.turn.livekit.cloud • Ensure proxies (ZScaler, corporate DPI) aren’t blocking or rewriting WebSocket/WSS. If you have a proxy, try from an environment without it. • Verify the client is using the fresh token you generate (no stale token). A 401/403 would show in the signaling logs. • If TURN/ICE is failing, force TURN over TLS (port 443) to see if UDP blocking is the issue. Why transcription can work while client join fails • Transcription proves the agent receives audio data (so agent dispatch & audio ingestion are OK). Client join can still fail if signaling or ICE/TURN paths from the client to LiveKit are blocked while server-side ingestion or the agent’s outbound connections are fine. If you want me to give a one-line fix right now • Paste the exact client-side error (console logs) and the result of the Connection Test (WebSocket/WebRTC/TURN). With that I’ll tell you the exact change to make (firewall rule, token fix, or TURN/TLS fallback) — no extra fluff. If you prefer, run these two commands and paste outputs: 1) From a failing client environment (or share Connection Test result): which checks fail? 2) From the production host: • A websocket connection test to your LiveKit URL (or error from the websocket client) I’ll convert the output into the exact change you need. Sources: Self-hosted deployments | LiveKit Documentation | Firewall Tips for LiveKit Connectivity | LiveKit | Diagnosing Connection Errors with the Connection Test Utility | LiveKit | Agents Framework | livekit/livekit_composite | DeepWiki | Understanding TLS in SIP | LiveKit
Thanks — I hear you: no firewall, no visible errors, agent works locally and even does transcription in prod, but clients can’t join. I’ll be direct and focused so we can pinpoint this quickly. What I need (please provide any you can) 1. Exact client-side logs when attempting to join (browser or React Native console). Even short snippets like "ICE failed" or "signal disconnected" help. 2. Result of the LiveKit Connection Test run from the failing client/network: which checks passed/failed (WebSocket, WebRTC, TURN)? 3. Tell me whether your client is using TURN or any custom TURN config (or the default LiveKit TURN). 4. Confirm the token the client actually uses is the freshly generated token (not cached). Any 401/403 in signaling logs? 5. From the production host (agent), paste a short log snippet around the time you try to join the room (include timestamps). Also say whether the agent shows as a participant in Agent Insights for that room. 6. If possible, try forcing relay-only on the client and tell me the result: ◦ Set
iceTransportPolicy: 'relay'
in the client's RTC config and retry joining. Why I’m asking • Transcription proving the agent receives audio narrows the problem to client-side signaling/ICE/TURN or token/join completion. If there truly are no errors visible, ICE/DTLS may be failing silently (common with NAT/relay issues or mobile WebRTC stacks). Forcing TURN (
relay
) or running the Connection Test will expose that. Immediate, high-value checks you can run now • Run Connection Test from a failing client and paste results. • Enable
iceTransportPolicy: 'relay'
and try again. If that fixes it, the problem is UDP/NAT/TURN access. • Paste the client join logs (even if they look empty). I’ll translate them into an exact one-line fix. If you prefer I can give the most likely single change to try first: set
iceTransportPolicy: 'relay'
and test. Tell me the result and I’ll give the next exact step. Sources: Firewall Tips for LiveKit Connectivity | LiveKit | Diagnosing Connection Errors with Connection Test Utility
Thanks — I’ll be direct. You say: agent works locally, agent in prod processes audio (transcription), agent name is correct, no firewall and no visible errors — but clients can’t join the room in production. That pattern means the problem is a silent client-side connectivity/ICE issue or a token/join completion mismatch, not the agent code. Do this now (fast, in this order) 1) Force TURN/relay on the client and test immediately • Add this when connecting and retry:
Copy code
room.connect(url, token, {
  rtcConfig: { iceTransportPolicy: 'relay' }
});
If this fixes it, UDP/NAT traversal is the issue and the fix is to ensure TURN reachability or keep relay for affected networks. 2) Run the LiveKit Connection Test from a failing client/network • Tell me which checks fail: WebSocket, WebRTC (ICE), or TURN. That identifies whether signaling or media relay is blocked. 3) Check the client-side join flow and logs • Even if “no error” is obvious, confirm the SDK emits a join result. Add:
Copy code
room.on('connected', () => console.log('joined'));
room.on('disconnected', (r) => console.log('disconnected', r));
room.on('connectionFailed', (e) => console.log('conn failed', e));
Paste any console output you get — even “no event” is useful. 4) Verify token usage & room name • Confirm the client uses the fresh token you generate and that the
room
in the token exactly matches the room you try to join (case-sensitive). A stale or wrong token often fails silently. 5) Quick production-host checks (if you can run them) • From the production host or client environment try a websocket probe to your LiveKit URL (wss://...). If it fails, signaling is blocked. If it succeeds, the problem is media (ICE/TURN). If you don’t want to run all tests: do step 1 (force relay). Report back the result (works / still fails) and the Connection Test outcome. With that single result I’ll give the exact one-line change you need (open firewall domain, switch TURN settings, or token fix). Sources: Diagnosing Connection Errors with the Connection Test Utility | LiveKit | Firewall Tips for LiveKit Connectivity | LiveKit | Configure ZScaler proxy for LiveKit connections | LiveKit | server-sdk-js | livekit/livekit_composite | DeepWiki | client-sdk-js | livekit/livekit_composite | DeepWiki
Thanks — I hear you: agent works, transcription works, clients still can’t join in production and you’re using Expo. I’ll be direct and give the next actionable steps to isolate and fix this. What to try right now (in this order) 1) Force TURN/relay in Expo (quick test) • Update your connect call to force relay-only:
Copy code
room.connect(url, token, {
  rtcConfig: { iceTransportPolicy: 'relay' }
});
• Retry on the same Expo device/network. If this fixes it, the problem is UDP/NAT traversal and TURN must be reachable from your clients. 2) Run the LiveKit Connection Test from the Expo device/network • Open https://livekit.io/connection-test on the same device (or run the ConnectionChecker if you have an SDK wrapper). • Tell me which checks fail: WebSocket, WebRTC (ICE), or TURN. 3) Capture minimal client-side logs in Expo • Add these handlers and paste any output you get (or say “no output”):
Copy code
room.on('connected', () => console.log('joined'));
room.on('disconnected', (r) => console.log('disconnected', r));
room.on('connectionFailed', (e) => console.log('conn failed', e));
console.log('ws', navigator && navigator.userAgent);
• Also check Expo/React Native console for WebRTC-related warnings (ICE/DTLS). 4) Quick network checks • Test the Expo device on a different network (phone hotspot). If it works on hotspot, the issue is network-level blocking on original network. • Ensure TCP/443 to *.turn.livekit.cloud and *.livekit.cloud is allowed. If none of the above helps, give me these three items and I’ll provide an exact one-line change: • The Connection Test results (which checks passed/failed). • The small Expo logs from step 3 (or confirm “no events emitted”). • Whether forcing
iceTransportPolicy: 'relay'
changed anything (works / still fails). I’ll stay focused: once you share those results I’ll give the precise fix (network rule, TURN configuration, or token change) — no extra fluff. Sources: Firewall Tips for LiveKit Connectivity | LiveKit | Diagnosing Connection Errors with Connection Test Utility
Thanks — good sign that you receive
participantConnected
. That means signaling, dispatch, and agent join are working. Let’s narrow what still fails. Tell me which of these describes your situation now (pick one or paste short logs): • Clients join the room but cannot publish audio (others don’t hear you). • Clients join but don’t receive other participants’ audio (no ontrack/playback). • You join and see agent transcription, but the client UI never shows "joined" or usable audio (despite participantConnected). • You see errors when trying to publish or subscribe (paste the exact error). • Everything looks joined but no media flows and no ICE/TURN errors in console. If you’re not sure, add these two quick checks and paste results: 1) On the Expo client, force relay and retry — did it change anything?
Copy code
room.connect(url, token, { rtcConfig: { iceTransportPolicy: 'relay' }});
2) Add brief logging in the client for media events and permission/state:
Copy code
room.on('connected', () => console.log('SDK: connected'));
room.on('participantConnected', p => console.log('SDK: participantConnected', p.identity, p.kind));
room.on('trackPublished', (p,t) => console.log('trackPublished', p.identity, t.source));
room.on('trackSubscribed', (p,t) => console.log('trackSubscribed', p.identity, t.kind));
room.on('subscriptionError', (err) => console.log('subscriptionError', err));
What I’ll do when you reply: • If publish/subscribe errors appear, I’ll give the exact one-line fix (TURN whitelist, token grant, or permission change). • If relay fixes it, I’ll show how to make TURN reliable for Expo clients. • If no change and no errors, I’ll guide you through a minimal reproducible test to isolate Expo/WebRTC behavior. Paste the one result (which case above) plus the outcome of forcing
iceTransportPolicy: 'relay'
and I’ll give the precise next step.
Thanks — helpful logs: you reach "connected" and
ontrack
appears, and you forced
iceTransportPolicy: 'relay'
. That tells me signaling, ICE, and track negotiation are completing. So we need to pin down what "still nothing" means and check a few final items. Quick checklist — tell me the result for each (one-line answers): 1) Can you hear any audio at all from other participants on the Expo device? (yes / no) 2) When you speak, do others hear you? (yes / no) 3) Do you see any published tracks in the UI (trackPublished / participant list)? (yes / no) 4) Any browser/Expo console warnings about autoplay, audio focus, or permissions? (paste if present) 5) Does
ontrack
carry audio that you can attach to an <Audio> component? Are you rendering/playing the received track? (describe how you consume tracks) If the answers above are mostly "no" (no audio in/out) try these two immediate checks: A) Explicitly subscribe and play the remote audio: • When
room.on('trackSubscribed', (participant, track) => ...)
fires, ensure you attach the track to playback. For React Native / rn-webrtc you may need to create an audio element or use the SDK's playback helpers. Log when
track
becomes
Subscribed
and when playback starts. B) Confirm local mic publish success: • After connecting, call
room.localParticipant.publishTrack(localAudioTrack)
and log the publish result and any
publicationFailed
or
trackPublished
events. If you prefer a direct test now: • Paste the outputs of these two event logs (exact lines): ◦ room.on('trackSubscribed', (p, t) => console.log('trackSubscribed', p.identity, t.source, t.kind)); ◦ room.localParticipant.on('trackPublished', pub => console.log('published', pub.track?.source, pub.track?.kind)); This will show whether tracks are actually subscribed/published at the SDK layer. One more important Expo note: • Mobile OS or Expo may mute autoplayed audio or require a user interaction to start audio output. If you haven’t requested audio focus or triggered a user interaction before playing tracks, the audio may be blocked silently. Try a tap-to-play action that starts audio playback, then see if remote audio plays. Send the five checklist answers and/or the two event logs and I’ll give the exact one-line change (playback hook, permission, or publish fix).
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!