Fast Refresh disconnects repeatedly on iOS 26 simulator (iPhone 17 Pro), stable on iOS 18 / Android
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 127k
- Forks
- 25.3k
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 4
Description
Description
On an iOS 26 simulator (iPhone 17 Pro, iOS 26.4 runtime), Fast Refresh / HMR disconnects from Metro within ~20–30 seconds of the app launching, with no visible JS error. The simulator shows the Fast Refresh disconnected. Reload app to reconnect. banner. Reloading briefly reconnects; the socket is dropped again shortly after. Interval to first drop varies from ~20 seconds to a few minutes but reproduces reliably.
The same Metro instance, started once, simultaneously serves an iPhone SE (2nd gen) / iOS 18 simulator and an Android emulator without any disconnections. Only the iOS 26 simulator drops, ruling out anything Mac-side (Metro, Watchman, port conflicts, firewall).
Reproduces on a stock npx @react-native-community/cli init project with zero custom code, native modules, or dev tooling — ruling out any userland cause.
Workaround (deterministic): hardcoding the bundle URL to http://127.0.0.1:8081/... in AppDelegate.bundleURL() (bypassing RCTBundleURLProvider) keeps Fast Refresh stable indefinitely. Reverting to the default provider reproduces the drop within 30 seconds. This strongly suggests the cause is hostname resolution / NSURLSession behavior specific to iOS 26 simulator runtimes.
Steps to reproduce
- On macOS with Xcode 26.x and the iOS 26.4 simulator runtime installed.
- Create a fresh project:
npx @react-native-community/cli init rnbaseline --version 0.83.1 cd rnbaseline - Start Metro:
yarn start - Build and run on iPhone 17 Pro / iOS 26.4 simulator:
yarn ios --simulator="iPhone 17 Pro" - Let the app idle on the default screen.
- Within ~20–30 seconds the
Fast Refresh disconnectedbanner appears.
Running the same app on an iPhone SE (2nd gen) / iOS 18 simulator or on an Android emulator in parallel shows no disconnection.
Mitigations tried (none resolved it except the workaround)
- Updated iOS 26 simulator runtime from 26.1 → 26.4 (#56183 referenced 26.4 as fixing other 26.x bugs) — no effect
- Removed all custom dev tooling (Reactotron, Storybook, etc.) — reproduces on stock RN init
yarn start --reset-cache— no effectwatchman watch-del-all && watchman shutdown-server— no effect- Verified no port 8081 conflicts with
lsof -i :8081— clean - Hardcoding
http://127.0.0.1:8081/...inAppDelegate.bundleURL()→ FIXES THE ISSUE (deterministic)
React Native Version
0.83.1
Affected Platforms
Runtime - iOS
Output of npx @react-native-community/cli info
System:
OS: macOS 26.3.1
CPU: (11) arm64 Apple M3 Pro
Memory: 128.09 MB / 18.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 22.21.1
path: /Users/uktam/.nvm/versions/node/v22.21.1/bin/node
Yarn:
version: 3.6.4
path: /Users/uktam/.nvm/versions/node/v22.21.1/bin/yarn
npm:
version: 10.9.4
path: /Users/uktam/.nvm/versions/node/v22.21.1/bin/npm
Watchman: Not Found
Managers:
CocoaPods:
version: 1.16.2
path: /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 25.2
- iOS 26.2
- macOS 26.2
- tvOS 26.2
- visionOS 26.2
- watchOS 26.2
Android SDK: Not Found
IDEs:
Android Studio: 2025.2 AI-252.25557.131.2521.14344949
Xcode:
version: 26.3/17C529
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.17
path: /opt/homebrew/Cellar/openjdk@17/17.0.17/libexec/openjdk.jdk/Contents/Home/bin/javac
Ruby:
version: 2.6.10
path: /Users/uktam/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli":
installed: 20.0.0
wanted: 20.0.0
react:
installed: 19.2.0
wanted: 19.2.0
react-native:
installed: 0.83.1
wanted: 0.83.1
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
Stacktrace or Logs
No stacktrace — this is a silent WebSocket drop, not a crash.
React DevTools console (client-side)
Cannot connect to Metro.
Try the following to fix the issue:
- Ensure that Metro is running and available on the same network
- Ensure that the Metro URL is correctly set in AppDelegate
URL: localhost:8081
Error: undefined
Metro server output
yarn start --verbose produces no error or warning at the moment the banner appears. The disconnect is silent from the server's perspective.
iOS 26 simulator network logs (log stream)
Filter used:
log stream --predicate 'process == "rnbaseline" AND subsystem == "com.apple.network"' --info
Every connection to the dev server resolves to both IPv4 and IPv6 endpoints and then runs Happy Eyeballs:
nw_endpoint_resolver_update [C22.1 Hostname#...:8081 in_progress resolver ...] Adding endpoint handler for IPv4#...:8081
nw_endpoint_resolver_update [C22.1 Hostname#...:8081 in_progress resolver ...] Adding endpoint handler for IPv6#...:8081
The IPv6 candidate fails (Metro listens only on IPv4):
nw_socket_handle_socket_event [C6365.1.1:1] Socket received CONNRESET event
nw_socket_handle_socket_event [C6365.1.1:1] Socket SO_ERROR [61: Connection refused]
[C6365.1.1 IPv6#...:8081 failed socket-flow ...] event: flow:failed_connect @0.005s, error Connection refused
and falls back to IPv4. One loopback TCP handshake was observed taking Duration: 2.099s — well above the expected sub-10ms for loopback — suggesting Happy Eyeballs contention.
Suspected cause (not fully confirmed)
The dual-stack resolution pattern appears in both "unstable" and "stable (with hardcode)" runs, so IPv4/IPv6 racing alone doesn't fully explain the intermittency. What is consistently true is that bypassing hostname-based resolution by hardcoding 127.0.0.1 stops the disconnect deterministically. The exact mechanism — IPv6 race, resolver caching, or some other iOS 26-specific NSURLSession behavior — needs maintainer investigation.
Suggested mitigation in RN
Either of these should mask the underlying iOS 26 simulator regression:
- Default
RCTBundleURLProviderto127.0.0.1(not the host's resolvable name) when running in an iOS 26+ simulator, or - Have Metro bind to both IPv4 and IPv6 by default so dual-stack resolution doesn't fail half its candidates.
Adjacent issues (context, not duplicates)
- #54845 — iPhone 17 Pro / iOS 26.1, different symptom (dev reload crash); closed as invalid.
- #54859 — iOS 26 TurboModule startup crash.
- #56183 — iOS 26 simulator CoreText bug, fixed in 26.4 runtime. Confirms Apple has shipped multiple broken simulator runtimes for iOS 26.
- External: iOS 26.4-beta WKWebView reports document WebSocket-to-IP-address connections taking seconds to establish or failing, with
0.0.0.0as workaround — suggests a shared NSURLSession regression.
MANDATORY Reproducer
Reproducible on clean 0.83.1 React Native CLI template
Screenshots and Videos
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with AppDelegate.bundleURL() and RCTBundleURLProvider, then reproduce the disconnect using the clean React Native 0.83.1 template and the supplied iOS 26 simulator steps. Compare the default hostname URL with the hardcoded 127.0.0.1 workaround; done means Fast Refresh remains connected on iOS 26 while existing iOS 18 and Android behavior remains stable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, react-native
- Domain
- mobile-dev, networking
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 32/100