Has anyone else observed intermittent first-navigation failures in Safari on iOS 26 when HTTP/3 0-RTT resumption is available?
Environment:
- iPhone 16 Pro, iOS 26.5.2 (23F84), Mobile Safari
- Wi-Fi with native IPv6
- Cloudflare-proxied HTTPS hostname
- Normal browsing, not Private Browsing
- Reproduced almost daily on the first visit; an immediate reload succeeds
Safari shows its native “cannot open the page because the server cannot be reached” page. The origin is healthy and neither the origin nor Cloudflare HTTP/security analytics records a corresponding HTTP failure.
We captured the iPhone network interface over USB and compared a failed navigation with the successful reload.
Failed navigation:
- DNS A, AAAA and HTTPS/SVCB answers completed normally.
- The HTTPS record advertised h3 and h2 with IPv4 and IPv6 hints.
- MobileSafari/WebKit opened several QUIC connections across the available IPv4 and IPv6 endpoints.
- Nearly all sent QUIC Initial packets plus 0-RTT application data.
- The edge replied promptly with Initial, Handshake and protected packets on both address families.
- Several flows did not settle and the edge retransmitted repeatedly.
- Safari also established a TCP/TLS fallback and received data, but still declared the navigation failed.
Successful reload:
- One IPv4 QUIC connection.
- Full handshake, without 0-RTT.
- Normal bidirectional protected traffic and the page loaded.
Control tests:
- Another proxied hostname succeeded with a full HTTP/3 handshake and no 0-RTT.
- A direct, non-proxied hostname succeeded over IPv6/TLS.
- HTTP/3 requests from the same Safari version otherwise received normal 200/204/302/304 responses.
This looks like a CFNetwork/Network.framework/libquic session-resumption or connection-racing recovery issue rather than a WebKit rendering or origin-server problem. The encrypted capture does not let us determine whether the early data was accepted or rejected by the edge.
Feedback filed: FB23764937.
Important reproduction note: 0-RTT has now been disabled on the affected production zone while HTTP/3 remains enabled. Therefore that hostname can no longer reproduce the original 0-RTT path. This is an intentional mitigation; it will not be re-enabled on production solely for testing.
Questions:
- Has anyone seen the same first-load failure followed by a successful reload on iOS 26?
- Is there a recommended way to collect CFNetwork/libquic diagnostics for a failure that occurs before an HTTP response exists?
- Should Safari replay the navigation after 0-RTT rejection or use the already-successful TCP/TLS fallback in this situation?
A raw packet capture is available to Apple through the private Feedback report on request, but is not posted publicly because it contains client network identifiers.Has anyone else observed intermittent first-navigation failures in Safari on iOS 26 when HTTP/3 0-RTT resumption is available?
Environment:
- iPhone 16 Pro, iOS 26.5.2 (23F84), Mobile Safari
- Wi-Fi with native IPv6
- Cloudflare-proxied HTTPS hostname
- Normal browsing, not Private Browsing
- Reproduced almost daily on the first visit; an immediate reload succeeds
Safari shows its native “cannot open the page because the server cannot be reached” page. The origin is healthy and neither the origin nor Cloudflare HTTP/security analytics records a corresponding HTTP failure.
We captured the iPhone network interface over USB and compared a failed navigation with the successful reload.
Failed navigation:
- DNS A, AAAA and HTTPS/SVCB answers completed normally.
- The HTTPS record advertised h3 and h2 with IPv4 and IPv6 hints.
- MobileSafari/WebKit opened several QUIC connections across the available IPv4 and IPv6 endpoints.
- Nearly all sent QUIC Initial packets plus 0-RTT application data.
- The edge replied promptly with Initial, Handshake and protected packets on both address families.
- Several flows did not settle and the edge retransmitted repeatedly.
- Safari also established a TCP/TLS fallback and received data, but still declared the navigation failed.
Successful reload:
- One IPv4 QUIC connection.
- Full handshake, without 0-RTT.
- Normal bidirectional protected traffic and the page loaded.
Control tests:
- Another proxied hostname succeeded with a full HTTP/3 handshake and no 0-RTT.
- A direct, non-proxied hostname succeeded over IPv6/TLS.
- HTTP/3 requests from the same Safari version otherwise received normal 200/204/302/304 responses.
This looks like a CFNetwork/Network.framework/libquic session-resumption or connection-racing recovery issue rather than a WebKit rendering or origin-server problem. The encrypted capture does not let us determine whether the early data was accepted or rejected by the edge.
Feedback filed: FB23764937.
Important reproduction note: 0-RTT has now been disabled on the affected production zone while HTTP/3 remains enabled. Therefore that hostname can no longer reproduce the original 0-RTT path. This is an intentional mitigation; it will not be re-enabled on production solely for testing.
Questions:
- Has anyone seen the same first-load failure followed by a successful reload on iOS 26?
- Is there a recommended way to collect CFNetwork/libquic diagnostics for a failure that occurs before an HTTP response exists?
- Should Safari replay the navigation after 0-RTT rejection or use the already-successful TCP/TLS fallback in this situation?
A raw packet capture is available to Apple through the private Feedback report on request, but is not posted publicly because it contains client network identifiers.
Resolved in iOS 26.6
For anyone following this issue, the user-visible failure has been corrected in iOS 26.6.
We reproduced the rejected 0-RTT path again on the same physical iPhone after upgrading it from iOS 26.5.2 to iOS 26.6. The QUIC/TLS logs still showed a cached ticket being offered, early data being sent, and early_data_accepted(0). The important difference was the client recovery:
- On iOS 26.5.2, the rejected early-data path ended with NSURLErrorDomain -1004 / NSPOSIXErrorDomain 61 and Safari displayed its “server cannot be reached” page. A manual reload was required.
- On iOS 26.6, Safari automatically abandoned the rejected path and retried with a fresh full HTTP/3 handshake within approximately 1.4–2.8 seconds. The retry returned HTTP 200 and no error page was shown.
Cloudflare’s engineering review confirmed that rejecting 0-RTT does not itself constitute a connection failure: the client is expected to continue with a normal handshake. The behavioural difference was therefore in the iOS client’s recovery after rejection.
A separate steady-state test with 0-RTT continuously enabled also completed normally. Immediate ticket reuse was accepted, while after approximately 26 hours Safari no longer offered a ticket and simply performed a successful full HTTP/3 handshake.
The original end-user issue reported here can therefore be considered fixed in iOS 26.6. The remaining discussion with Cloudflare concerns only the precise lifetime and rejection policy for early data; it no longer produces the Safari failure on the corrected iOS version.