writeup

my apple watch paired fine. then it forgot.

kisnner obando · september 2026 · watchos 27.2 · xcode 27 / device hub · macos 27.2 · the repo · status: fixed later, see the follow-up

update, october 3: this turned out to be fixed by updating the iphone to ios 27.2, not by anything on the watch. the follow-up has the evidence and its limits: the watch wasn't broken. my iphone was behind. what follows is the investigation as i wrote it at the time.

a writeup of an apple watch ultra 2 that disappeared from xcode 27 and never came back. this one isn't solved. what i have is a much narrower description of the failure than "it won't connect", built from logs on the mac and on the watch, one experiment that changed my theory, and a dead end with an independent pairing host. it's reported to apple as FB24924229.

tl;dr

the symptom

$ xcrun devicectl list devices
iPhone (2)   available (paired)   iPhone 15 Pro Max
iPad         available (paired)   iPad Pro 12.9-inch
             (no watch)
$ xcrun devicectl manage pair --device <watch>
The specified device was not found (1000)

device hub showed "currently unavailable — must be nearby". installing from the iphone's watch app filled halfway and stalled. bluetooth, wi-fi, the cable, developer mode and the app itself were all ruled out first. the full list is in what-i-tried.md.

1. the pairing succeeds, then the channel closes

remotepairingd on the mac shows a complete, successful pairing, followed by a close:

22:21:41.314  PairSetup server done -- client authenticated
22:21:41.314  tcp-79: Pairing session of kind setupManualPairing succeeded
22:21:41.344  tcp-79: received error reading message        <-- +30 ms
22:21:41.345  tcp-79: authenticated -> invalidated
22:21:41.663  DeviceHub: Beaconing pairing session explicitly ended by client

my first write-up called that 30 ms close the bug. it wasn't.

2. a control: the iphone does the same thing

after resetting location & privacy, the iphone also had to be re-paired, one minute before the watch, on the same mac:

setup succeededchannel closedreconnect
iphone10:54:22.173+36 ms+1.4 s verifyManualPairing → available
watch10:55:08.951+29 msnone

the close is normal: setup ends, then the device reconnects on a verified session. what's missing is the watch's reconnect. i rewrote the repo and the apple report to say that. an earlier draft had used an ipad reconnect as the control, which wasn't a fresh setup, so it wasn't a fair comparison either.

3. watches pair into the mac

the mac finds an iphone by browsing _remotepairing._tcp. the watch never advertised that, and i'd listed "the watch doesn't announce itself" as the main hypothesis. reading a live log stream during pairing showed the flow is the other way round for a watch:

22:21:16  remotepairingd: Started listening for network pairing   <-- sheet opened
22:21:41  setupManualPairing succeeded
22:21:41  DeviceHub: Beaconing pairing session explicitly ended  <-- sheet closes itself

the watch connects to the mac's _remotepairing-pairable-host._tcp listener, and that listener exists only while device hub's pair nearby device… sheet is open. the sheet closes itself ~300–400 ms after setup. so the watch not advertising is probably by design, and a new theory showed up: maybe the watch tries to reconnect, but there's nothing left to connect to.

4. keeping the mac listening

reopening the sheet by hand left a 15 s gap and nothing came back. to close the gap i wrote watch-pair-keeper.sh: it tails remotepairingd, and the moment device hub drops the listener it clicks pair nearby device… again through system events, then reports whether the watch verified. before using it live i replayed a captured log through it to check the timings.

22:53:00.613  setupManualPairing succeeded (watch)     closed at +305 ms
22:53:01.533  mac listening again                      gap: 615 ms
22:53:23.502  Network pairing peers updated. Total count: 1   <-- the watch is back
22:53:23.558  PairingData(startNewSession: true, kind: setupManualPairing)
22:53:23.559  DeviceHub: Presenting pairing challenge   <-- a new code
22:53:33.642  setupManualPairing succeeded (watch)     closed again at +286 ms

that disproved my theory and gave a better answer. the watch does reconnect. but it asks for a new pair-setup, not pair-verify, as if it had forgotten the pairing it finished 23 seconds earlier. the mac stored the pairing and was listening; the watch didn't use its side. setup, close, setup, close.

one false positive worth noting: the script flagged a verifyManualPairing at 22:53:59. it was the ipad. the script only counts a verify when the next authenticated line carries the watch's udid prefix, which is why it didn't report success.

5. the watch's own logs

a watch sysdiagnose (crown + side button, then out through the iphone) showed remotepairingdeviced starting the pairing normally: it resolves the mac's advert, connects over wi-fi, lockdownShouldDisableDevicePairing: NO, "manual pairing in progress". then the archive has no lines from any process between 22:21:34.1 and 22:21:48, so the watch side of the close at 22:21:41 isn't there. (the first archive that came through was the iphone's. the filename says iPhone-OS vs Watch-OS; check it before digging in.)

6. an independent host

if the mac side can't be changed, maybe it can be replaced. pymobiledevice3 11.19.1 has remote pair-host, which advertises a pairable host and accepts a device-initiated pairing. the watch listed it under developer ▸ paired macs ▸ other devices, asked for the watch passcode, and then never opened a tcp connection.

apple's host is reached over ipv6 link-local; pymobiledevice3 binds 0.0.0.0 and only publishes an a record. so i wrapped it (pair_host_dualstack.py) to listen on both families and advertise the aaaa record too. same result: no connection, over either. device hub also runs a "beaconing" session that pymobiledevice3 doesn't. whether the watch needs it, i don't know yet.

where it stands

mistakes i made along the way

takeaways

links