We develop a healthcare emergency-alerting app with a native watchOS companion app. We've hit a network routing issue on watchOS that we cannot work around with any public API, and it breaks a safety-critical flow (triggering an emergency alarm from the watch).
Environment
- watchOS 26.5 on Apple Watch SE3, paired with iPhone SE 2nd Gen on iOS 26.5
- Watch app deployment target: watchOS 9.0
- Plain
URLSession(async/await), default configuration pluswaitsForConnectivity = false,allowsExpensiveNetworkAccess = true,allowsConstrainedNetworkAccess = true - HTTPS to our own backend (valid public TLS certificate, no pinning)
Steps to reproduce
- Pair the watch with the iPhone. Both on the same known Wi-Fi network.
- On the iPhone: turn OFF Wi-Fi and cellular data. Keep Bluetooth ON.
- The watch remains connected to its known Wi-Fi network (or would be, if the system brought the radio up).
- Trigger any HTTPS request from the watch app (foreground).
Expected
Since the companion iPhone has no internet, the watch should satisfy the request over its own Wi-Fi.
Actual
The request is routed through the companion link (ipsec1,
"companion preference: prefer" in the logs) and fails after the TLS
handshake dies inside the tunnel:
Error Domain=NSURLErrorDomain Code=-1200
"An SSL error has occurred and a secure connection to the server cannot be made."
_kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9816 (errSSLClosedNoNotify)
The watch never fails over to its own Wi-Fi, no matter how many times we retry or how long we wait. The same request succeeds within seconds if the user disables Bluetooth on the iPhone (watch then joins Wi-Fi directly), or restores the iPhone's internet.
What we already tried
waitsForConnectivity = truedoesn't help; a path exists (the tunnel), it just doesn't work.- Fresh
URLSessionper retry, backoff retries still routed via the tunnel. - Per TN3135 we understand low-level networking is not available to a normal
app: we prototyped
NWConnectionwithprohibitedInterfaceTypes = [.other], and indeed on deviceNWPathMonitorstays.unsatisfiedeven when the watch has working Wi-Fi, exactly as TN3135 describes. So Network framework is not an escape hatch for us, and we are not looking to abuse the audio-streaming/CallKit carve-outs.
Questions
- Is the companion-preferred routing supposed to fail over to the watch's own Wi-Fi when the iPhone is reachable over Bluetooth but has no internet? If yes, on what timescale, and is there anything an app can do to help the system notice the dead path sooner?
- Is there ANY supported way for a foreground watchOS app to express
"do not use the companion link for this request"? We found only the
private
_companionProxyPreferenceSPI, which we obviously can't ship. - If the answer to both is "no", what is the recommended pattern for safety-critical requests in this state is failing fast and instructing the user to disable iPhone Bluetooth really the intended UX?
Related earlier reports of the same behavior: https://developer.apple.com/forums/thread/759321 https://developer.apple.com/forums/thread/107964