CTCellularPlanStatus.checkValidity(ofToken:) throws Couldn't communicate with a helper application on iOS 26

Hello,

We are using the UPI device validation APIs on iOS 26+ in a production banking/UPI app, and we are seeing a recurring failure from CoreTelephony that we need guidance on.

API / entitlement

  • Framework: CoreTelephony
  • API: CTCellularPlanStatus.checkValidity(ofToken:)
  • Related: CTCellularPlanStatus.token()
  • Entitlement: com.apple.developer.upi-device-validation
  • Availability: iOS 26.0+

Minimal call site do { let isValid = try await CTCellularPlanStatus.checkValidity(ofToken: token) // isValid == true/false -> expected outcomes } catch { // Unexpected: API throws instead of returning Bool print(error.localizedDescription) }

Error error.localizedDescription is:

  • English: Couldn't communicate with a helper application.
  • Same failure also appears with a localized Hindi message on Hindi-locale devices.

This is distinct from checkValidity(ofToken:) returning false (token/SIM mismatch). Here the API throws, so we cannot tell whether the token is valid.

In production we currently only have this localizedDescription from telemetry.

Production observations (large fleet, last few days)

  • Observed only on production user devices so far; we have not reproduced it reliably on lab hardware.
  • Occurs across multiple iOS 26.x builds (notably 26.5.2, 26.5, 26.6; also seen on 26.0-27.0). Not limited to a single patch.
  • Seen on many iPhone models (not one SKU).
  • Latency is bimodal for the same error string:
    • large share fails in under 100 ms (immediate)
    • another large share fails after about 2-10+ seconds (timeout-like)
  • Observed under Wi-Fi, cellular (4G/5G), and No Connection / radio-not-ready conditions.
  • Same device can emit many identical failures within about 1 second when validity is checked from multiple call sites concurrently.
  • Token generation (CTCellularPlanStatus.token()) and successful checkValidity work for the vast majority of users; this throw is a smaller but material failure class.

Questions for Apple

  1. Is "Couldn't communicate with a helper application." an expected / documented failure mode of checkValidity(ofToken:) (for example CommCenter/XPC unavailable, radio not ready)?
  2. What conditions typically trigger this error from checkValidity(ofToken:)?
  3. Recommended client handling: retry (with backoff)? treat as transient and skip forcing re-binding? surface to user?
  4. Does validation require cellular registration / SIM ready state even when docs indicate internet is not required?
  5. Any known issues on specific iOS 26.x builds, dual-SIM, eSIM, or airplane-mode transitions?
  6. Is concurrent checkValidity from multiple tasks unsupported / unsafe?

Because this is currently production-only and not reliably reproducible on lab devices, we cannot attach a sysdiagnose or Instruments trace at this time. We can share aggregated production telemetry and API details via Feedback Assistant if helpful.

Thank you.

Answered by DTS Engineer in 900122022

Consider this:

import Foundation

func main() {
    print(CocoaError(.xpcConnectionInvalid, userInfo: [:]).localizedDescription)
    // prints: Couldn’t communicate with a helper application.
}

main()

This is NSXPCConnectionInvalid, which is equivalent to XPC_ERROR_CONNECTION_INVALID, which is in turn documented in the xpc_connection_create man page. In short, something went wrong with XPC and the XPC subsystem is not able to automatically retry.

This error has a variety of potential causes:

  • During development you often see if when the XPC service is broken some some reason.
  • Or when the sandbox prevents you from accessing it.
  • You can also see it when you connect to an anonymous listener and the remote peer terminates for some reason.

So, this is a very general error and it’ll be hard to make progress without a sysdiagnose log. Which is tricky when you can’t reproduce the problem.

I have two suggestions for you:

  • In your standard app, you could implement a delay and retry. That may or may not help but, even if it doesn’t, it’d still make a useful data point (assuming it return it via your telemetry).
  • In selective builds — like the ones you use for internal testing, or ship to beta testers — you could add code that explicitly requests a sysdiagnose log. I talk about this idea in Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Consider this:

import Foundation

func main() {
    print(CocoaError(.xpcConnectionInvalid, userInfo: [:]).localizedDescription)
    // prints: Couldn’t communicate with a helper application.
}

main()

This is NSXPCConnectionInvalid, which is equivalent to XPC_ERROR_CONNECTION_INVALID, which is in turn documented in the xpc_connection_create man page. In short, something went wrong with XPC and the XPC subsystem is not able to automatically retry.

This error has a variety of potential causes:

  • During development you often see if when the XPC service is broken some some reason.
  • Or when the sandbox prevents you from accessing it.
  • You can also see it when you connect to an anonymous listener and the remote peer terminates for some reason.

So, this is a very general error and it’ll be hard to make progress without a sysdiagnose log. Which is tricky when you can’t reproduce the problem.

I have two suggestions for you:

  • In your standard app, you could implement a delay and retry. That may or may not help but, even if it doesn’t, it’d still make a useful data point (assuming it return it via your telemetry).
  • In selective builds — like the ones you use for internal testing, or ship to beta testers — you could add code that explicitly requests a sysdiagnose log. I talk about this idea in Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

CTCellularPlanStatus.checkValidity(ofToken:) throws Couldn't communicate with a helper application on iOS 26
 
 
Q