URLSession is broken in iOS 18.4 RC Simulator

I'm seeing fully reproducible issues with URLSession on iOS 18.4 RC Simulator running from Xcode 16.3 RC. URLSession seems to get into a broken state after a second app run. The following sample succeeds in fetching the JSON on first app run but when the app is closed and ran again it fails with one of these errors:

  • Error: Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost."
  • Error: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out."

I'm wondering if this something related to my OS setup or is this due to internal URLSession changes in iOS 18.4. Already submitted as FB17006003.

Sample code attached below:

import SwiftUI
@main
struct NetworkIssue18_4App: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State private var message: String = ""
var body: some View {
VStack {
Text(message)
Button("Try Again") {
Task {
await fetch()
}
}
}
.task {
await fetch()
}
}
private func fetch() async {
message = "Loading..."
let url = URL(string: "https://poetrydb.org/title/Ozymandias/lines.json")!
let session = URLSession.shared
do {
let response = try await session.data(from: url)
print("Response: \(response)")
message = "Success, data length: \(response.0.count)"
} catch {
print("Error: \(error)")
message = "Error: \(error.localizedDescription)"
}
}
}
Answered by DTS Engineer in 831246022

Well, that’s not good. I ran your test and was able to immediately reproduce the problem.

Written by fastred in 777999021
Already submitted as FB17006003.

Thank you! I checked on your bug and the relevant folks have seen it.

Your bug mentioned HTTP storage, so I tweaked your code to use an ephemeral session and the problem went away.

let session: URLSession = {
return URLSession(configuration: .ephemeral)
}()

Ephemeral sessions disable three standard things: cookie storage, the URL cache, and credential storage. So I tried creating a default session with those disabled:

let session: URLSession = {
let config = URLSessionConfiguration.default
config.httpCookieStorage = nil
config.urlCache = nil
config.urlCredentialStorage = nil
return URLSession(configuration: config)
}()

Annoying, that didn’t fix the problem. So the ephemeral session is disabling something beyond those three standard things.

And that’s me out of obvious ideas )-: Clearly this is a bug that the URLSession folks will have to investigate.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Seeing same issue on second app launch. Sometimes see the failures as “failed to parse response“ or “network connection was lost” errors.

Well, that’s not good. I ran your test and was able to immediately reproduce the problem.

Written by fastred in 777999021
Already submitted as FB17006003.

Thank you! I checked on your bug and the relevant folks have seen it.

Your bug mentioned HTTP storage, so I tweaked your code to use an ephemeral session and the problem went away.

let session: URLSession = {
return URLSession(configuration: .ephemeral)
}()

Ephemeral sessions disable three standard things: cookie storage, the URL cache, and credential storage. So I tried creating a default session with those disabled:

let session: URLSession = {
let config = URLSessionConfiguration.default
config.httpCookieStorage = nil
config.urlCache = nil
config.urlCredentialStorage = nil
return URLSession(configuration: config)
}()

Annoying, that didn’t fix the problem. So the ephemeral session is disabling something beyond those three standard things.

And that’s me out of obvious ideas )-: Clearly this is a bug that the URLSession folks will have to investigate.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

One of my colleagues suggested that something might be broken in our HTTP/3 support. That gels with the symptoms you’ve described:

  • When you first run the app, it doesn’t know whether the server supports HTTP/3, so it defaults to HTTP/2.

  • As part of that exchange, it learns that the server supports HTTP/3 and remembers that.

  • The next time you run, it starts out with HTTP/3, which then fails.

Based on that, I tried the following tweak to your test:

var req = URLRequest(url: url)
#if targetEnvironment(simulator)
req.assumesHTTP3Capable = false
#endif
let response = try await self.session.data(for: req)

With that, things starting behaving themselves.

Obviously this is less than ideal — HTTP/3 is your friend! — but it should tide you over for the moment.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@DTS Engineer Quinn, thank you for checking this so quickly. It makes sense why it works initially and only breaks on further request.

Do you know why this bug seems to occur only on the Simulator? Do real devices use a different URLSession implementation?

req.assumesHTTP3Capable does not solve the problem for me.

Things do work with an ephemeral session.

Written by fastred in 831361022
Do you know why this bug seems to occur only on the Simulator?

There are substantial differences between iOS and the iOS simulator, especially when it comes to networking. Most of the time those differences don’t matter, but every now and again you encounter a case where they do. Some of those cases are known limitations — you can’t test a Network Extension provider in the simulator, for example — but others are just bugs.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I'm dealing with a similar issue now 🤔 also appearing on the 2nd and later app launches – only to discover that there's probably something about the SSL/TLS configuration conflicting with the web I'm attempting to display in WKWebView. Adding an Info.plist exception:

NSExceptionRequiresForwardSecrecy = false;

for the domain patched it for me for now, another option is setting

configuration.websiteDataStore = .nonPersistent()

on your WKWebView where applicable (which is probably similar to using ephemeral configuration on URLSession).

Yet I guess none of these shouldn't really differ from the device behaviour & it's not an actual fix, could be just a hot patch for a wider variety of inconsistencies. Curiously it really only started failing with 18.4 Beta/RC Simulator, 18.3 is just fine, no matter the backing macOS (15.3.2 or 15.4 Beta/RC).

Initially I found that clearing some caches (AlternativeService.sqlite file in particular) in app's sandbox (partially) recovered web views to be working, yet that wasn't really effective for a production hotfix. Thus I hope this will be addressed in the Release version of the Simulator. 🙏😄

Hopefully this could help somebody else dealing with a very mysterious issue during this Beta cycle. 🫠

Reported as FB16846380.

Written by misacek in 831749022
I'm dealing with a similar issue now

But yours occurs on real devices, right?

Because this thread has heretofore been about the simulator.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Not really, my issue also appears only in the Simulator – when I tested the app bundle on the real 18.4 Beta/RC device, it worked just fine.

Now, the more I'm testing it, the “trick“ with Info.plist exceptions seems not to work anymore, only setting the .websiteDataStore = .nonPersistent() allows me at least render the desired website right now.

Got a bunch of logged issues on the way, as follows.

1️⃣ Error caught in webView(_:didFailProvisionalNavigation:withError:):

// 18.4 Simulator exclusive
0x1040bbc18 - [pageProxyID=12, webPageID=13, PID=8501] WebPageProxy::didFailProvisionalLoadForFrame: frameID=16, isMainFrame=1, domain=NSURLErrorDomain, code=-1001, isMainFrame=1, willInternallyHandleFailure=0
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSErrorFailingURLStringKey=https://www.kiwi.com/, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <EE8D03C0-F32B-4DC7-9D77-4E3F5A5694C2>.<2>, NSErrorFailingURLKey=https://www.kiwi.com/, networkTaskMetricsPrivacyStance=NotEligible, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <EE8D03C0-F32B-4DC7-9D77-4E3F5A5694C2>.<2>"
), NSLocalizedDescription=The request timed out., _WKRecoveryAttempterErrorKey=<WKReloadFrameErrorRecoveryAttempter: 0x6000002557c0>, networkTaskDescription=LocalDataTask <EE8D03C0-F32B-4DC7-9D77-4E3F5A5694C2>.<2>, _kCFStreamErrorDomainKey=4, NSUnderlyingError=0x600000c11d70 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, _kCFStreamErrorCodeKey=-2102}
0x103a4a818 - [pageProxyID=12, webPageID=13, PID=9737] WebPageProxy::didFailProvisionalLoadForFrame: frameID=16, isMainFrame=1, domain=NSURLErrorDomain, code=-1005, isMainFrame=1, willInternallyHandleFailure=0
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSErrorFailingURLStringKey=https://www.kiwi.com/, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <764262C2-9135-4B73-B98C-A0404487BC91>.<2>, NSErrorFailingURLKey=https://www.kiwi.com/, networkTaskMetricsPrivacyStance=NotEligible, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <764262C2-9135-4B73-B98C-A0404487BC91>.<2>"
), NSLocalizedDescription=The network connection was lost., _WKRecoveryAttempterErrorKey=<WKReloadFrameErrorRecoveryAttempter: 0x6000002ddd40>, networkTaskDescription=LocalDataTask <764262C2-9135-4B73-B98C-A0404487BC91>.<2>, _kCFStreamErrorDomainKey=4, NSUnderlyingError=0x600000c96760 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={_kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, _kCFStreamErrorCodeKey=-4}

2️⃣ Random log mentioning browser engine entitlements:

// Also shown with 18.3 Simulator
Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "((target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.rendering AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.networking AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.webcontent))" UserInfo={NSLocalizedFailureReason=((target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.rendering AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.networking AND target is not running or doesn't have entitlement com.apple.developer.web-browser-engine.webcontent))}>
0x12700e0b0 - ProcessAssertion::acquireSync Failed to acquire RBS assertion 'XPCConnectionTerminationWatchdog' for process with PID=8136, error: (null)

3️⃣ Random log containing QUIC & network issues:

// 18.4 Simulator exclusive
quic_conn_change_current_path [C4.1.1.1:2] [-fc2c137b006e9a75] tried to change paths, but no alternatives were found
...repetitively...
Task <854C1530-6678-4EBA-8279-353D981F20E0>.<3> finished with error [-1017] Error Domain=NSURLErrorDomain Code=-1017 "cannot parse response" UserInfo={_kCFStreamErrorCodeKey=-1, NSUnderlyingError=0x600000c81d10 {Error Domain=kCFErrorDomainCFNetwork Code=-1017 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x6000021454f0 [0x1e6ebb4f0]>{length = 16, capacity = 16, bytes = 0x100201bb8efb256a0000000000000000}, _kCFStreamErrorCodeKey=-1, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <854C1530-6678-4EBA-8279-353D981F20E0>.<3>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <854C1530-6678-4EBA-8279-353D981F20E0>.<3>"
), NSLocalizedDescription=cannot parse response, NSErrorFailingURLStringKey=https://firebaseremoteconfig.googleapis.com/v1/projects/kiwi-debug/namespaces/firebase:fetch?key=XXXXXXXXXX, NSErrorFailingURLKey=https://firebaseremoteconfig.googleapis.com/v1/projects/kiwi-debug/namespaces/firebase:fetch?key=XXXXXXXXX, _kCFStreamErrorDomainKey=4}
// (Similar issue for plain URL https://duckworth.finance-prod.skypicker.com/currencies-config)

4️⃣ Some Simulator stuff from Console app:

nw_endpoint_flow_failed_with_error [C16.1.1.4 18.245.62.104:443 in_progress socket-flow (satisfied (Path is satisfied), interface: en0[802.11], expensive, uses wifi)] already failing, returning
nw_connection_copy_protocol_metadata_internal_block_invoke [C16] Client called nw_connection_copy_protocol_metadata_internal on unconnected nw_connection
quic_conn_change_current_path [C12.1.1.1:2] [-e80eabd0b655b188] tried to change paths, but no alternatives were found
[app<com.skypicker.Skypicker((null))>:9733] client not entitled to get limitationsForInstance: <Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.process-state, NSLocalizedFailureReason=Client not entitled, RBSPermanent=false}>
0x1048f0818 12 Server protocol violation 0x02
0x1048f0818 12 Control stream closed but connection is alive
nw_flow_service_writes Failing write request <nw_write_request> [57: Socket is not connected]
Task <3643AD6D-70F8-4862-B533-79F663D61C69>.<2> HTTP load failed, 555/0 bytes (error code: -1017 [4:-1])
nehelper sent invalid response: <dictionary: 0x1e6e8d320> { count = 1, transaction: 0, voucher = 0x0, contents =
"XPCErrorDescription" => <string: 0x1e6e8d4b8> { length = 18, contents = "Connection invalid" }
}
nw_connection_add_timestamp_locked_on_nw_queue [C7] Hit maximum timestamp count, will start dropping events

I've just updated to Xcode 16.3 RC 2 & tested (no change), RC Simulator runtime seems like hasn't changed from RC1.

iOS 18.3 Simulator still works fine, even if launched from latest Xcode RC.

Feel free to reach me if needed, I can test whatever I'd be able to, will continue investigating as well. 👍

URLSession is broken in iOS 18.4 RC Simulator
 
 
Q