pymobiledevice3 shipped 59 releases since phoneshell's pin, including a macOS 27 tunnel fix
A kernel change on macOS 27 broke a default tunnel for every developer-service command; a fix shipped nine days after phoneshell's pinned version. The claim is a version comparison, not a reproduction: this checkout has the right macOS and no phone to test it on.
pymobiledevice3 shipped 59 releases between 7 September and 14 October 2026, including a fix, in v11.13.0 on 16 September, for a macOS 27 kernel change that broke its default tunnel discovery for every developer-service command. phoneshell's requirements.txt pins pymobiledevice3==11.8.0, nine days older than that fix and 23 version numbers behind the latest. The checkout this note was written from is itself running macOS 27.0, the exact version the regression targets, but has no phone attached and no pymobiledevice3 installed, so the claim below is a version comparison, not a reproduced failure.
What broke on macOS 27, and what fixed it
pymobiledevice3's default way to reach an iOS developer service on macOS, the --native tunnel, works by finding remoted's existing RSD connection to the device through the kernel's net.inet.tcp.pcblist* sysctls, then attaching to it without needing Xcode or a password prompt beyond the one the tunnel itself needs. Starting with macOS 27, that sysctl family answers with only the calling process's own sockets unless the caller runs as root, so the lookup came back empty and every --native command failed with "could not find remoted's RSD connection to the tunnel address." Release v11.13.0, 16 September 2026 (commit dce8f604, PR #1952), replaced the sysctl read with a single sample from nettop, which is Apple-signed with the com.apple.private.network.statistics entitlement and so sees every process's sockets regardless of caller privilege. The fix needs no root and no Xcode, and the release notes report it costs about 0.1 seconds.
Which of phoneshell's own calls sit in the affected path
phoneshell does not import pymobiledevice3's tunnel machinery directly. It shells out to the installed CLI for two bring-up checks, both in device.py: developer_mode_check runs pymobiledevice3 amfi developer-mode-status, and ddi_check runs pymobiledevice3 mounter list, with its suggested fix command being mounter auto-mount. Both are developer-service commands of the kind the release note describes as defaulting to --native on macOS. A separate pymobiledevice3 release, v11.19.0, documents that from iOS 17.4 onward auto_mount() specifically needs an RSD tunnel to install the Cryptex1 DDI a modern device requires, and that the CLI "sets up a no-root tunnel and retries by itself" when a library caller is not already holding one. phoneshell's bench results describe a physical iPhone 17 Pro Max running iOS 26.6, well past that 17.4 line.
| phoneshell call site | CLI command | Needs a developer-service tunnel | Affected by the pinned version |
|---|---|---|---|
developer_mode_check, device.py:293 | amfi developer-mode-status | Developer-service command; whether it reaches for --native specifically is not documented in the commands we read | Unverified: no device attached in this checkout to test against |
ddi_check, device.py:321 | mounter list / auto-mount | Confirmed by v11.19.0's own notes for iOS 17.4+, which phoneshell's target device is well past | Unverified: same limitation |
phone_lan_ip, device.py:364 | lockdown info | Plain lockdown, not a developer service; not described as needing RSD in any release note read | Not affected, on current evidence |
The honest state of this claim is a version comparison, not a reproduction. The macOS 27 regression is specific to the root-requiring --native tunnel mode; pymobiledevice3's own CLI is documented elsewhere as falling back to a no-root userspace tunnel when it does not already hold one, and whether phoneshell's two checks, run without sudo, ever reach the broken code path or always take the fallback is not something we could determine by reading the release notes or phoneshell's code alone. What is verifiable without a device is simpler: the pin predates the fix, and it has predated every one of the 59 releases since.
What it means for pinning a device-automation dependency
- A security-relevant pin still needs a floor, not just a ceiling. Exact-version pins (
==, as phoneshell uses throughoutrequirements.txt) buy reproducibility, but they also freeze in any bug that existed when the pin was set, including ones tied to a host OS version newer than the pin itself. - Read a dependency's release notes for your own host OS by name, not just your target device OS. This fix was never about the iPhone's iOS version; it was about the Mac doing the automating moving to macOS 27, which phoneshell's own bring-up checks do not query or warn about.
- Before trusting a version-gap argument like this one, get a repro. We could not, in this checkout: no device, no pymobiledevice3 binary. The next person running phoneshell's actual bench, on an actual macOS 27 Mac with a cable-connected phone, can settle it in one command.
Check it yourself
- The regression and fix: pymobiledevice3 release v11.13.0, 16 September 2026, commit
dce8f604,https://github.com/doronz88/pymobiledevice3/releases/tag/v11.13.0. - The pin:
grep pymobiledevice3 requirements.txtin the phoneshell repo shows==11.8.0. - Release count since the pin:
gh api repos/doronz88/pymobiledevice3/releases --paginate | jq -r .[].tag_name, counting tags betweenv11.8.0and the current latest. - The call sites:
sed -n '287,330p' phoneshell/device.pyfordeveloper_mode_checkandddi_check. - The reproduction this note could not run: on a macOS 27 Mac with an iPhone attached over USB,
pip install pymobiledevice3==11.8.0 && pymobiledevice3 mounter list, compared against the same command on the current release.
What would prove this wrong
The claim is that phoneshell's pinned version, run on a macOS 27 Mac, hits the broken native-tunnel path for at least one of its two developer-service checks. Test: run developer_mode_check and ddi_check against pymobiledevice3==11.8.0 on a macOS 27 Mac with a real device attached, then again against the latest release. If both succeed identically on 11.8.0, the checks take the no-root fallback and this note overstates the exposure. We expect at least one to fail on 11.8.0 and succeed after an upgrade. We will publish the comparison, or say we did not run it, by 15 November 2026.
Sources
- pymobiledevice3 release v11.13.0, 16 September 2026 (native tunnel / RSD port discovery fix, commit dce8f604, PR #1952)
- pymobiledevice3 release v11.19.0 (auto_mount RSD tunnel requirement from iOS 17.4, RSDRequiredError)
- pymobiledevice3 GitHub releases index, v11.8.0 through v11.31.0 (read 14 October 2026)
- phoneshell source: requirements.txt, device.py (developer_mode_check, ddi_check, phone_lan_ip) (read 14 October 2026)