Summary
GADS v5.7.0 fails to set up iOS 27 (beta) devices. The DDI mount succeeds, but go-ios's trailing Hangup cleanup command fails because iOS 27 closes the mobile_image_mounter lockdown connection immediately after the mount. GADS treats this cleanup error as a fatal mount failure and resets the device in a ~12s retry loop, never reaching WDA.
Device
| Field |
Value |
| Device |
iPhone 14 (iPhone14,7) |
| UDID |
00008110-00040994117A602E |
| iOS |
27.0 (27A5209h) |
| Xcode |
26.3 (17C529) |
| GADS |
v5.7.0 |
| go-ios |
v1.0.202 |
Error
Failed to mount Developer Disk Image (DDI) for device `00008110-00040994117A602E` - failed to mount DDI: MountImage: HangUp command failed: Write: only 0 bytes were written instead of 229
Repeats every ~12s in an infinite retry loop.
Root cause
The go-ios personalized DDI mount flow (personalized_image_mounter.go:67-130) is:
- Query identifiers → get nonce → get Apple TSS signature
sendUploadRequest → stream DMG bytes → waitForUploadComplete
mountPersonalizedImage ← the actual mount; returns nil (succeeds)
hangUp ← sends {"Command":"Hangup"} over the same lockdown connection
On iOS 27, the device closes the mobile_image_mounter lockdown connection immediately after step 3 succeeds. Step 4's write gets 0 bytes → Write: only 0 bytes were written instead of 229 → wrapped as MountImage: HangUp command failed.
GADS's mountDeveloperImage() (provider/devices/ios.go:104) treats any non-"already mounted" error as fatal and calls resetWithError, which resets the device and triggers the retry loop — even though the DDI is already mounted.
This is not a lockdown-vs-CoreDevice protocol issue. The MountImage/Personalized plist command works; only the trailing Hangup is rejected. Xcode's devicectl uses CoreDevice and never sends Hangup, so it doesn't hit this.
Note: the latest go-ios (v1.0.218) adds a QueryPersonalizationManifest optimization but still sends the same Hangup — so bumping go-ios alone won't fix this.
Fix
When imagemounter.MountImage fails with "HangUp command failed", log a warning and re-connect to verify the DDI is mounted via ListImages. If an image is mounted, proceed to WDA. If verification fails, reset as before.
if strings.Contains(err.Error(), "HangUp command failed") {
logger.ProviderLogger.LogWarn("ios_device_setup", ...)
return d.verifyDDIMounted()
}
verifyDDIMounted opens a fresh NewImageMounter + ListImages on a new lockdown connection, independent of the closed mounter connection.
Verification
go build ./provider/devices/ ✅
go vet ./provider/devices/ ✅
- Live device verification not yet done — needs the iPhone 14 on iOS 27. The fix is testable by confirming setup proceeds past DDI mount to
setupTunnelIfNeeded() → WDA install.
Related
Summary
GADS v5.7.0 fails to set up iOS 27 (beta) devices. The DDI mount succeeds, but go-ios's trailing
Hangupcleanup command fails because iOS 27 closes themobile_image_mounterlockdown connection immediately after the mount. GADS treats this cleanup error as a fatal mount failure and resets the device in a ~12s retry loop, never reaching WDA.Device
00008110-00040994117A602EError
Repeats every ~12s in an infinite retry loop.
Root cause
The go-ios personalized DDI mount flow (
personalized_image_mounter.go:67-130) is:sendUploadRequest→ stream DMG bytes →waitForUploadCompletemountPersonalizedImage← the actual mount; returnsnil(succeeds)hangUp← sends{"Command":"Hangup"}over the same lockdown connectionOn iOS 27, the device closes the
mobile_image_mounterlockdown connection immediately after step 3 succeeds. Step 4's write gets 0 bytes →Write: only 0 bytes were written instead of 229→ wrapped asMountImage: HangUp command failed.GADS's
mountDeveloperImage()(provider/devices/ios.go:104) treats any non-"already mounted" error as fatal and callsresetWithError, which resets the device and triggers the retry loop — even though the DDI is already mounted.This is not a lockdown-vs-CoreDevice protocol issue. The
MountImage/Personalizedplist command works; only the trailingHangupis rejected. Xcode'sdevicectluses CoreDevice and never sendsHangup, so it doesn't hit this.Note: the latest go-ios (v1.0.218) adds a
QueryPersonalizationManifestoptimization but still sends the sameHangup— so bumping go-ios alone won't fix this.Fix
When
imagemounter.MountImagefails with"HangUp command failed", log a warning and re-connect to verify the DDI is mounted viaListImages. If an image is mounted, proceed to WDA. If verification fails, reset as before.verifyDDIMountedopens a freshNewImageMounter+ListImageson a new lockdown connection, independent of the closed mounter connection.Verification
go build ./provider/devices/✅go vet ./provider/devices/✅setupTunnelIfNeeded()→ WDA install.Related
hangUpcall is atios/imagemounter/imagemounter.go:180(v1.0.202)