Skip to content

Question: concurrent RSD connections to same device — anyone else seeing this? #1656

@aluedeke

Description

@aluedeke

Question: concurrent RSD connections to same device — anyone else seeing this?

What I'm seeing

When two processes open an RSD-based service connection to the same device at the same time, one of them fails during the RemoteXPC / HTTP/2 handshake with Connection was terminated abruptly. Staggering the two calls by ~100–300ms is enough to make both succeed. pymobiledevice3's default for syslog live goes through usbmuxd so this is invisible in normal usage — I only hit it when forcing RSD with --rsd HOST PORT.

Why I'm asking here

I first hit this in go-ios, which always auto-selects RSD on iOS 17+ whenever a tunnel is available. Two simultaneous calls there produce HTTP/2 RST INTERNAL_ERROR from the device. Since it looked like it might be client-side, I tried to reproduce with pymobiledevice3 forcing RSD — and got the same race with a slightly different error surface.

That leads me to think this is device-side behavior (the device's remoted rejecting two concurrent HTTP/2 handshakes on the RSD port), not something specific to either client library. But I'd love a sanity check before concluding that.

Questions

  1. Has anyone else run into this when running multiple concurrent pymobiledevice3 RSD-based sessions against the same device?
  2. Is there a known way to work around it beyond staggering calls or falling back to usbmuxd where possible?
  3. Is this already documented / reported to Apple somewhere I missed?

Environment

  • pymobiledevice3: 9.8.1
  • macOS: 26.4.1
  • Device: iPhone, iOS 18.7.1

Reproducer

With a running tunnel, pick the RSD host + port and run two simultaneous syslog streams:

(timeout 3 pymobiledevice3 syslog live --rsd <addr> <port> 2>/tmp/p1.err > /tmp/p1.out) &
(timeout 3 pymobiledevice3 syslog live --rsd <addr> <port> 2>/tmp/p2.err > /tmp/p2.out) &
wait
wc -l /tmp/p1.out /tmp/p2.out
cat /tmp/p1.err /tmp/p2.err

Result:

0 /tmp/p1.out
6201 /tmp/p2.out

2026-04-14 09:57:16 mbal pymobiledevice3.__main__[49902] ERROR Connection was terminated abruptly

Which side wins is effectively random. Adding sleep 0.3 between the two launches makes both succeed reliably.

The equivalent test with go-ios through its RSD path fails similarly with readDataFrame: got RST frame with error code: INTERNAL_ERROR, which is the device emitting an HTTP/2 RST frame during the handshake.

Observations that back the device-side hypothesis

  • Reproduces with two completely different clients (pymobiledevice3 and go-ios) that share no code
  • Only reproduces on the RSD path; the same service (com.apple.os_trace_relay) accessed over usbmuxd has no such issue even with many parallel clients
  • Multiplexing many services inside one RemoteXPC session is fine — it's only the establishment of two independent sessions that races
  • ~100ms stagger is enough to avoid it

Thanks for any pointers 🙏

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions