CloudKit subscription pushes keep being delivered to an app that no longer has the container entitlement

We ship two iOS apps from the same team that are designed to work together:

  • App A – uses CloudKit container "Container A"
  • App B – uses CloudKit container "Container B"

Until App B version 1.5, App B also had Container A in its com.apple.developer.icloud-container-identifiers entitlement, because it read a few records from App A's container directly. App B called registerForRemoteNotifications() for its own container's subscriptions.

App A creates a CKDatabaseSubscription on the shared database (and CKQuerySubscriptions on the private database) with notificationInfo.alertBody set, so that a participant gets a visible push when the owner shares something.

Problem: on devices where App B 1.5 (or earlier) had run, every push generated by App A's subscriptions is delivered to both App A and App B. App B shows a banner with App A's alert text under App B's name. This still happens after we shipped App B 1.6, which removed Container A from App B's entitlements entirely (App B 1.6 never touches that container).

What we have tried on an affected device, none of which stopped the deliveries to App B:

  1. Updating App B to 1.6 (entitlement removed).
  2. Deleting App B and reinstalling it from the App Store.
  3. In App B, calling unregisterForRemoteNotifications() and then registerForRemoteNotifications() again on next launch.
  4. Rebooting the iPhone.

Devices that installed App B 1.6 fresh (never ran 1.5) do not receive these pushes, so the behavior seems to come from a registration that was created while App B still had the entitlement and that is not being cleaned up.

Questions:

  1. Is the association "APNs token of App B ↔ Container A" kept on the CloudKit server side, and is there any way for the app (or for us as the developer) to remove it once the entitlement is gone?
  2. If it cannot be removed explicitly, does it expire? Roughly how long after the app stops registering for that container?
  3. Is there a recommended way to design this (two apps, one container) so that alert pushes from one app's subscriptions are not shown by the other app? We would rather not switch App A to content-available pushes with local notifications, because silent pushes are not delivered reliably when the app has been force-quit.

Environment: iOS 26, App A 4.7.x, App B 1.6.x, Production CloudKit environment. We have also filed a DTS request with the actual identifiers and can provide device logs or a sysdiagnose if helpful.

Thank you.

Does your App B ever create a subscription to observe changes on container A? If yes, it may be worth checking if the subscription still there (because you didn't remove the subscription when dropping container A)? This doesn't sound intuitive, given you've completely removed container A from App B's entitlements, but there may have corner situation there.

If you have a device that can reproduce the issue, manage to add access to container A back, then try to run fetchAllSubscriptions(completionHandler:), and check if it returns the old subscription.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Thank you for looking into this.

App B has never created any subscription on container A. It only read records from container A's private and shared databases (BirthHandover, PregnancyPhoto, and shared zones), and all of its subscriptions were created on its own container B (two CKDatabaseSubscriptions: "kimito-private-db" and "kimito-shared-db").

So there should be no leftover subscription on container A belonging to App B. What we observe looks more like a device-level push registration for container A that was created while App B still had the entitlement, and that is not being removed after the entitlement was dropped.

If it would help, I can build a test version of App B that temporarily includes the container A entitlement, run fetchAllSubscriptions on container A from an affected device, and report what it returns. I can also provide a sysdiagnose from the affected device. Please let me know which would be most useful.

Yeah, for debug purpose, it's worth doing the following:

  • Check if container A has any unintentional subscription left behind by using fetchAllSubscriptions.
  • Check if the association between container A and app B is removed in the developer portal. You can find the iCloud Container Assignment page using the steps described TN3164.

If the checks don't reveal any hint, I’d suggest that you file a feedback report with a sysdiagnose, and share your report ID here. For how to capture a sysdiagnose with the CloudKit profile, see TN3163.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.