SDK version: client-sdk-swift 2.14.0 and 2.14.1 (both reproducible)
Platform: macOS 26.5 (Tahoe), arm64
App: menubar SwiftUI client embedding LiveKit via a thin wrapper SDK
Symptom
Every connect to a Room crashes with EXC_BAD_ACCESS within ~5–8 s of Room.connect(...). Two distinct stacks observed in the same SDK version, both deep inside Room:
Stack A — on first SDP offer
SignalClient._process(signalResponse:)
→ Room.signalClient(_:didReceiveOffer:offerId:)
→ Room.publisherShouldNegotiate(force:)
→ direct field offset for Room._regionManager
→ EXC_BAD_ACCESS (KERN_INVALID_ADDRESS at 0x28)
Stack B — during initial connect sequence
Room.fullConnectSequence(_:_:)
→ @objc closure #1 in Room.fullConnectSequence(_:_:)
→ EXC_BAD_ACCESS (KERN_INVALID_ADDRESS at 0x20)
The crashing thread in stack A is the main thread doing a SwiftUI layout pass; the corrupting work is on a webrtc dispatch thread (webrtc::Thread::ProcessMessages → PhysicalSocketServer::WaitPoll) that the Room delegate hop returns into.
Memory corruption, not a null deref
Bad-access addresses differ across reproductions: 0x28, 0x10001002a, 0x7a326d303934685d (ASCII garbage, looks like a stomped value), 0x20. Same SDK version, same call site. That pattern points at a use-after-free of a Room-owned object (likely _regionManager, which appears as a direct field offset for symbol in stack A) rather than a static null pointer.
What rules out our deployment
Reproduced identically against three independent LiveKit servers:
- LiveKit Cloud (production environment)
- LiveKit Cloud (staging environment)
- Self-hosted
livekit-server via the project's own dev docker-compose, fronted by a local realtime worker registering against ws://localhost:7880
Same SDK version, same call stack, same 0x28 subtype on stack A regardless of which server is on the other end. Server-side ICE/TURN/SFU is therefore not the variable.
Reproducibility
100% — five .ips files from a single afternoon, every voice session attempted ended this way. The connect path always reaches Room.publisherShouldNegotiate (stack A) or dies during fullConnectSequence (stack B); there is no successful session on this build.
Tried
- 2.14.1 → crash (stack A consistently)
- 2.14.0 → crash (stack A primarily, stack B once)
- 2.13.0 → could not test; SDK removed
LiveKitSDK.setTracing(_:) and the Span(label:) initializer used by our ConnectTracing, so it does not compile against our codebase without source changes.
Happy to share .ips files privately if useful — they contain workspace IDs / user identifiers that I'd rather not paste in a public issue.
Environment
- SwiftPM, Swift 6 language mode
- LiveKit dependency surface used:
Room.connect(...), ConnectOptions(enableMicrophone: true) (publish-during-join), Room.prepareConnection for prewarm, LiveKitSDK.setLogLevel, LiveKitSDK.setTracing
- Transitive:
livekit-uniffi-xcframework 0.0.6, webrtc-xcframework 144.7559.6
SDK version:
client-sdk-swift2.14.0 and 2.14.1 (both reproducible)Platform: macOS 26.5 (Tahoe), arm64
App: menubar SwiftUI client embedding LiveKit via a thin wrapper SDK
Symptom
Every connect to a
Roomcrashes withEXC_BAD_ACCESSwithin ~5–8 s ofRoom.connect(...). Two distinct stacks observed in the same SDK version, both deep insideRoom:Stack A — on first SDP offer
Stack B — during initial connect sequence
The crashing thread in stack A is the main thread doing a SwiftUI layout pass; the corrupting work is on a webrtc dispatch thread (
webrtc::Thread::ProcessMessages → PhysicalSocketServer::WaitPoll) that theRoomdelegate hop returns into.Memory corruption, not a null deref
Bad-access addresses differ across reproductions:
0x28,0x10001002a,0x7a326d303934685d(ASCII garbage, looks like a stomped value),0x20. Same SDK version, same call site. That pattern points at a use-after-free of aRoom-owned object (likely_regionManager, which appears as adirect field offset forsymbol in stack A) rather than a static null pointer.What rules out our deployment
Reproduced identically against three independent LiveKit servers:
livekit-servervia the project's own dev docker-compose, fronted by a local realtime worker registering againstws://localhost:7880Same SDK version, same call stack, same
0x28subtype on stack A regardless of which server is on the other end. Server-side ICE/TURN/SFU is therefore not the variable.Reproducibility
100% — five
.ipsfiles from a single afternoon, every voice session attempted ended this way. The connect path always reachesRoom.publisherShouldNegotiate(stack A) or dies duringfullConnectSequence(stack B); there is no successful session on this build.Tried
LiveKitSDK.setTracing(_:)and theSpan(label:)initializer used by ourConnectTracing, so it does not compile against our codebase without source changes.Happy to share
.ipsfiles privately if useful — they contain workspace IDs / user identifiers that I'd rather not paste in a public issue.Environment
Room.connect(...),ConnectOptions(enableMicrophone: true)(publish-during-join),Room.prepareConnectionfor prewarm,LiveKitSDK.setLogLevel,LiveKitSDK.setTracinglivekit-uniffi-xcframework0.0.6,webrtc-xcframework144.7559.6