gorgeous-hydrogen-44699
03/05/2026, 1:22 PMtall-airline-16756
03/05/2026, 1:22 PMtall-airline-16756
03/05/2026, 1:22 PM100 Trying) and believes the first INVITE timed out.
Why you’re likely seeing this in your logs
• LiveKit sent an INVITE to the SIP provider. The provider either didn’t send a provisional response fast enough or the provisional response was lost, so LiveKit retransmitted the INVITE.
• The provider noticed the retransmission and returned 482 to indicate the new INVITE was a duplicate of one already being processed.
• Your agent stack surfaced that 482 as an error (TwirpError) rather than treating it as informational/duplicate.
Troubleshooting steps to confirm root cause
1. Capture SIP traces (Wireshark) or request provider SIP logs for the failing calls to get the exact message timing:
◦ Confirm when the initial INVITE left LiveKit and whether a 100 Trying or other provisional response arrived.
◦ Check the timing between the first INVITE and the retransmission that elicited 482.
1. Check if the provider sends a fast provisional response:
◦ If the provider sends 100 Trying immediately, that should stop retransmissions. If not, that’s a likely cause.
1. Correlate with network/transport:
◦ Note whether you’re using UDP vs TCP/TLS to the provider. UDP is more susceptible to lost provisional responses and retransmits; TCP/TLS reduces those retransmits.
1. Review retry/timeout behavior in your flow:
◦ Confirm if your application layer or call logic is also retrying the INVITE on timeouts. Multiple layers retrying can produce duplicates.
◦ If the app is retrying, stop redundant retries and allow the SIP stack to handle retransmissions.
1. Treat 482 as a duplicate in error handling (if appropriate):
◦ If the call proceeds on the original request, 482 can often be treated as informational. Avoid immediately failing the call on seeing a 482 if follow-up responses indicate the original request succeeded.
Practical mitigations
• Ask the SIP provider to ensure they send an immediate 100 Trying on receiving INVITEs so retransmits stop.
• Prefer TCP/TLS transport for trunks if your provider supports it to reduce lost provisional messages.
• Ensure only one layer is retrying INVITEs (either the SIP stack or your app) to avoid duplicated INVITEs.
• Enable SIP message captures for intermittent failures so you can show exact timing to the provider.
If you’d like, I can help narrow this further — could you share:
• Whether your trunk uses UDP or TCP/TLS.
• A short timeline from the SIP capture or provider logs showing the initial INVITE, any provisional responses, and your retransmission timestamps.
• How frequently this happens (single occurrence vs multiple calls).
With that info I can help interpret the trace and recommend the most targeted change.
Sources: server-sdk-kotlin | livekit/livekit_composite | DeepWiki | sip | livekit/livekit_composite | DeepWiki | Understanding TLS in SIP | LiveKit | Best practices for managing webhook event streams | LiveKit | SIP Lifecycle Management Agent | LiveKit Documentationgorgeous-hydrogen-44699
03/05/2026, 1:26 PMtall-airline-16756
03/05/2026, 1:26 PMws_url to localhost and ran everything in one instance (in-memory Redis), and that stopped the 482 Request Merged errors. You want to split components for scaling but avoid the retransmission/482 issues. I’ll summarize why this happened and give clear, practical steps to scale safely.
Why switching to localhost removed the error
• Running everything in one process with in-memory state removes network hops and timing variability. Provisional responses (like 100 Trying) and SIP state updates arrive quickly, so LiveKit didn’t retransmit the INVITE.
• When you split components, transient network latency, lost provisional responses, or misconfigured connections can make LiveKit retransmit an INVITE. The SIP provider then returns 482 Request merged because it sees a duplicate INVITE.
What to check and change when splitting components for scale
1. Use a shared, persistent Redis (not in-memory)
◦ All LiveKit processes must share the same Redis instance so signaling and SIP state stay consistent across nodes.
◦ Ensure Redis is reachable with low latency from all LiveKit services. High latency can cause state divergences that lead to retransmits.
1. Set ws_url to a resolvable external address (not localhost) for distributed components
◦ Use an external DNS or IP that other services can resolve (for example <wss://livekit.example.com>), so workers and agents connect reliably across hosts.
◦ Confirm firewall/DNS allow those connections.
1. Transport & provisional responses for SIP
◦ Prefer TCP or TLS for the SIP trunk if your provider supports it. TCP/TLS reduces lost provisional responses compared to UDP.
◦ Ensure your SIP provider sends immediate provisional responses (e.g., 100 Trying). Lack of a quick provisional response commonly triggers retransmits.
1. Ensure network and port connectivity
◦ Open SIP port(s) and the RTP range across hosts: sip_port (5060/5061) and rtp_port (10000-20000).
◦ If you use NAT, enable correct external IP/STUN/TURN so media and signaling ACKs/provisionals are routable.
1. Review timeouts and retry behavior
◦ Avoid adding extra application-layer retries that re-send INVITEs on top of the SIP stack retransmissions.
◦ Where possible, let the SIP layer handle retransmits and treat a 482 as informational if the original INVITE is still being processed.
1. Logging & tracing to confirm root cause
◦ Capture SIP traces (Wireshark) or obtain provider SIP logs for a failing call to see:
▪︎ When the first INVITE was sent.
▪︎ When (or if) a 100 Trying arrived.
▪︎ When the retransmission that caused 482 was sent.
◦ Correlate those timestamps with LiveKit logs to identify whether Redis/network delays or lost provisional responses caused retransmits.
Practical checklist to apply now
• Deploy a central Redis reachable by all LiveKit instances.
• Update ws_url to the cluster’s external address (e.g., wss://<your-domain>), not localhost.
• Confirm SIP trunk uses TCP/TLS (or that UDP is reliable and provisionals aren’t being dropped).
• Ensure sip_port and rtp_port ranges are open and route correctly.
• Turn on detailed SIP/message logging and capture a trace for an occurrence so we can verify timings.
If you want, share these specific details and I’ll help interpret the trace and point to the exact configuration tweak:
• Are you using UDP or TCP/TLS for the SIP trunk?
• Redis host/URL (masked is fine) and whether it’s reachable from all nodes (ping/latency).
• A small SIP trace or timestamps around a failing call showing the initial INVITE, any provisional responses, and the retransmission that caused 482.
I can then help pinpoint whether this is network/provisionals, Redis/state synchronization, or a retry from your app layer and recommend the exact change to prevent 482s when you scale.
Sources: Understanding TLS in SIP | LiveKit | server-sdk-ruby | livekit/livekit_composite | DeepWiki | server-sdk-js | livekit/livekit_composite | DeepWiki | sip | livekit/livekit_composite | DeepWiki | How We Built a Globally Distributed WebRTC Mesh Networkgorgeous-hydrogen-44699
03/05/2026, 1:28 PMtall-airline-16756
03/05/2026, 1:28 PMws_url now (external host or IP is fine to paste)?
◦ Can you confirm all LiveKit processes can resolve and connect to that address with low latency? (A quick ping or curl/wss check and round-trip time helps.)
1. Redis details
◦ Confirm Redis host/port and whether TLS is enabled for Redis connections.
◦ From each LiveKit node, can you run a quick latency check to Redis (e.g., ping or redis-cli ping) and share approximate latency?
1. Example log lines (full context)
◦ Paste the most recent full error block (including a few lines before/after) where TwirpError / sip status 482 appears.
1. SIP trace or provider logs
◦ Capture the SIP transaction for one failing call (Wireshark or the provider’s SIP logs). We need the timing of:
▪︎ First INVITE send time
▪︎ Any provisional responses (100 Trying, 180 Ringing, etc.) and their timestamps
▪︎ The retransmitted INVITE timestamp that resulted in 482
◦ If you can’t share full PCAP, copy the SIP message timestamps and the top lines of each SIP message.
1. Frequency and pattern
◦ How often does this happen (every call, intermittent, only under load)?
◦ Does it correlate with high load, high Redis latency, or network spikes?
If you prefer, start by sharing 1–4 now (transport, ws_url, Redis latency, recent error logs). That will let me decide whether the next step should be examining SIP traces or checking Redis/network metrics. Once I see the logs/trace I’ll point to the exact configuration or network change to prevent the duplicate INVITEs and 482 responses.gorgeous-hydrogen-44699
03/05/2026, 1:35 PMtall-airline-16756
03/05/2026, 1:36 PM100 Trying immediately on receipt of INVITE. That prevents retransmits at the sender.
1. Verify network and NAT behavior
◦ Ensure there’s no intermediate device dropping UDP provisional responses.
◦ If you must use UDP, make sure NAT mappings and firewall rules preserve and forward responses reliably.
1. Keep Redis shared and ws_url correct
◦ You already moved to central Redis and separated SIP — keep ws_url resolving to the external host (not localhost) so all nodes are consistent and respond with low latency.
1. Gather trace data if issue continues
◦ Capture SIP traces for a failing call (PCAP or provider logs). We need timestamps for:
▪︎ First INVITE
▪︎ Any provisional responses (100 Trying, 180 Ringing)
▪︎ Retransmitted INVITE that triggered the flood/482
◦ Also capture round-trip latency to Redis and ws_url connectivity from each node.
Quick checks you can do right now
• What transport is configured at the SIP trunk? (UDP / TCP / TLS)
• Can you change it to TCP/TLS and test a few calls?
• Run a short SIP capture for one failed call and paste the INVITE + provisional response timestamps if switching transport doesn’t fix it.
If you want, share the current trunk URI (you can mask credentials) and whether you can switch to TCP/TLS — I’ll give the exact config suggestion and the minimal firewall rules you’ll need.
Sources: Understanding TLS in SIP | LiveKit | Diagnosing Connection Errors with the Connection Test Utility | LiveKit