We are getting sdk and livekit server state mismat...
# ask-ai
f
We are getting sdk and livekit server state mismatch issue. Getting connected disconnected issue simultaneously.
t
Thanks for reaching out, hardeep. 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’re seeing simultaneous connect/disconnects. I’m responding about the SDK ↔️ server state mismatch (STATE_MISMATCH) you described and can help diagnose it. To narrow this down, please tell me: 1. Which SDK and exact version are you using (Web, iOS, Android, Flutter, JS, or another)? 2. Are you seeing a client
DisconnectReason.STATE_MISMATCH
or any disconnect reason string in your client logs? 3. Can you reproduce the issue reliably? If so, when does it happen (network change, app backgrounding, crash, after a specific time)? 4. Do you call
room.disconnect()
/
room.dispose()
(or platform-equivalent cleanup) before reconnecting? 5. Can you share relevant server logs or webhook events around the time of the problem (e.g.,
participant_left
with reason
STATE_MISMATCH
) — if you can paste the timestamped lines here, that helps. Quick guidance while you gather info: • STATE_MISMATCH is related to the WebRTC/media path (not signaling) and often happens when a client disconnects uncleanly, crashes, or a network blackout prevents ICE keep-alives (~20s) from reaching the server. • Race conditions can appear if the client tries to reconnect while the server is still cleaning up the previous session. Send the SDK/version, a short client log excerpt showing the connect/disconnect events, and any server/webhook lines you can share. I’ll use that to recommend targeted steps next (cleanup code, reconnection timing, or log analysis). Sources: Understanding the STATE_MISMATCH Disconnect Reason | Server-side | livekit/livekit_composite | DeepWiki | How We Built a Globally Distributed WebRTC Mesh Network | client-sdk-flutter | livekit/livekit_composite | DeepWiki | client-sdk-android | livekit/livekit_composite | DeepWiki
f
im using livekit_client: ^2.6.0 in flutter application.
t
Thanks — that’s helpful. I’m responding about the STATE_MISMATCH / connect–disconnect behavior for the Flutter
livekit_client: ^2.6.0
SDK. I can help diagnose this, but I need a few quick details and will give immediate checks you can run. Please provide: • A short client log snippet (timestamped) showing the connect and disconnect events around the failure. Include any
DisconnectReason
or error text. • Any server/webhook logs (timestamps) for the same window, especially
participant_left
or similar events. • Whether this happens reliably and when it occurs (network change, app background/foreground, long idle, after a crash). Quick checks to run now: • Confirm you call
LiveKitClient.initialize()
(if used) and that you call
room.disconnect()
and
room.dispose()
before attempting a reconnect. • Reproduce while capturing logs and watch for
DisconnectReason.STATE_MISMATCH
. That reason indicates the WebRTC/media path timed out or the session was cleaned up server-side (often after an unclean client disconnect or ICE keep-alives stopping ~20s). • Test on a stable network (no Wi‑Fi <> cellular switches) to see if network transitions trigger it. • If you use any custom reconnection logic, try a short delay (e.g., 1–2s) before reconnecting to avoid racing the server cleanup. Send the logs and reproduction notes and I’ll analyze them and recommend the precise fix (cleanup code, reconnection timing, or server-side clues).
f
Im getting stateMismatch in DisconnectReason on RoomDisconnectedEvent we are disposing room before initializing new room.
t
Thanks — I’m looking at your
DisconnectReason.STATE_MISMATCH
on
RoomDisconnectedEvent
and that you already call
room.dispose()
before creating a new room. Good info — here are focused next steps to diagnose and fix this. Please try these checks (in order): 1. Confirm lifecycle calls • Ensure you call
room.disconnect()
(graceful leave) before
room.dispose()
.
dispose()
without a prior
disconnect()
can cause the server to see an abrupt disconnect. • Ensure
LiveKitClient.initialize()
was called once at app startup (not repeatedly). 1. Add a short delay before creating a new room • After
room.dispose()
, wait 1.5–3 seconds before initializing/connecting a new Room. This avoids racing the server’s cleanup of the prior peer connection. 1. Capture targeted logs • Reproduce with verbose logs around the event and paste these lines: ◦ Client timestamps showing: connect attempt,
RoomEvent.connected
, any
RoomEvent.disconnected
with
DisconnectReason.STATE_MISMATCH
◦ Any reconnection attempts and the timing relative to dispose/create • If possible, include server/webhook lines for the same timestamps (e.g.,
participant_left
with reason). 1. Check for network interruptions or app backgrounding • See if this happens after app background/foreground or during Wi‑Fi/cellular switches. STATE_MISMATCH often follows ICE keep-alive timeouts (~20s) or abrupt network loss. 1. Review custom reconnection logic • If you retry connects automatically, add a small backoff (1–3s) and avoid immediately reusing previous session state. Ensure each new connection uses a fresh token and Room instance. If those steps don’t stop the issue, please send: • SDK version (you already sent 2.6.0 — confirmed) • A short client log snippet (timestamps) showing connect → disconnect with the
STATE_MISMATCH
reason and the exact dispose/create timing. I’ll analyze the logs and recommend exact code changes or deeper server-side checks.
f
Copy code
await _room!.connect(
  url,
  token,
  connectOptions: const ConnectOptions(
    timeouts: Timeouts(
      connection: Duration(seconds: 30),
      peerConnection: Duration(seconds: 20),
      publish: Duration(seconds: 20),
      debounce: Duration(seconds: 5),
      iceRestart: Duration(seconds: 20),
      subscribe: Duration(seconds: 20),
    ),
  ),
);
do i need to make changes in the timeout?
t
Thanks — I’m responding about whether your
ConnectOptions
timeouts need changing to address
STATE_MISMATCH
. Short answer: you may not need large changes, but two timeouts are most relevant and worth adjusting/testing: •
peerConnection
/
iceRestart
—
STATE_MISMATCH
is tied to the WebRTC/media path. If ICE keep‑alives or peer connection checks stop (network loss, app backgrounding), the server can time out the peer connection. Increasing
peerConnection
and
iceRestart
from 20s to something slightly larger (e.g., 30–45s) can reduce false positives where the server closes a session while the client is still trying to reconnect. •
connection
— 30s is reasonable for signaling; keep as is unless you see signaling-specific timeouts. Practical steps: 1. Try bumping
peerConnection
and
iceRestart
to 30–45s and reproduce. 2. Keep a small delay (1.5–3s) after `room.disconnect()`/`room.dispose()` before creating a new Room to avoid races with server cleanup. 3. Use verbose logs when reproducing and watch for
DisconnectReason.STATE_MISMATCH
timestamps vs. your reconnect attempts. If you try increasing those two values and still see state mismatch, paste a short client log (timestamps around connect/disconnect) and I’ll suggest the next diagnostic steps.
f
ok so now
Copy code
await Future.delayed(const Duration(seconds: 3));
await _room!.connect(
  url,
  token,
  connectOptions: const ConnectOptions(
    timeouts: Timeouts(
      connection: Duration(seconds: 30),
      peerConnection: Duration(seconds: 45),
      publish: Duration(seconds: 20),
      debounce: Duration(seconds: 5),
      iceRestart: Duration(seconds: 45),
      subscribe: Duration(seconds: 20),
    ),
  ),
);
t
Thanks — I’m responding about your updated code (3s delay and `peerConnection`/`iceRestart` set to 45s). Quick check: does the
STATE_MISMATCH
still occur after these changes? If yes, please paste a short timestamped client log showing: •
RoomEvent.connected
•
RoomEvent.disconnected
with
DisconnectReason.STATE_MISMATCH
• The
room.disconnect()
/
room.dispose()
timing and the subsequent
connect()
attempt Also confirm you call
room.disconnect()
before
room.dispose()
and that each new connect uses a fresh token. With those logs I’ll analyze the timing and recommend next steps (further timeout tuning, reconnection backoff, or server-side clues).