CKRecordZone deleted when second user accepts zone-wide CKShare

I'm seeing a critical issue where a custom CKRecordZone is consistently deleted server-side when a second iCloud account interacts with a zone-wide CKShare. I've reproduced this 20+ times across two days and have exhausted every client-side fix I can think of. Looking for guidance on what might be going wrong.

Setup

  • Container: iCloud.com.cohencooks (production app on App Store)
  • Custom CKRecordZone in owner's private database
  • Zone-wide CKShare(recordZoneID:) (iOS 15+ zone sharing)
  • SwiftData with ModelConfiguration(cloudKitDatabase: .none) — no automatic CloudKit mirroring
  • Acceptance via CKFetchShareMetadataOperationCKContainer.accept(metadata) (no UICloudSharingController)

Minimal reproduction

// 1. Owner creates zone + share
let zone = CKRecordZone(zoneName: "MyZone")
try await privateDB.save(zone)

let share = CKShare(recordZoneID: zone.zoneID)
share[CKShare.SystemFieldKey.title] = "My Share" as CKRecordValue
share.publicPermission = .readWrite
let (results, _) = try await privateDB.modifyRecords(saving: [share], deleting: [])

// 2. Owner pushes ~500 records to zone — all succeed

// 3. Second user (different iCloud account) accepts share
let metadata = try await container.shareMetadata(for: shareURL)
try await container.accept(metadata)  

// 4. Owner's next CKFetchRecordZoneChangesOperation → zoneNotFound (code 26)
// Zone is permanently gone. allRecordZones() confirms deletion.

What I observe

Three distinct failure patterns depending on configuration:

Pattern 1 — publicPermission = .readWrite, no addParticipant: Zone dies instantly after acceptance. First push notification shows cloudkit.share changed (zone alive), second push notification returns zoneNotFound. The non-owner never successfully wrote anything.

Pattern 2 — publicPermission = .none with explicit addParticipant: Zone survives acceptance and 2-3 minutes of bidirectional sync (non-owner pulls 578 records, pushes meal plans back). Then a push notification arrives and the zone is gone. This is dramatically better than Pattern 1 but still fails.

Pattern 3 — Container destabilization after repeated testing: After 20+ create/delete cycles in one day, zones die from the owner's own push notifications — no second device involved at all. The container appears to enter an unstable state.

Inconsistent state after deletion

Here's something that might help narrow this down. After one of the zone deletions, I deployed the same build to a second device signed into a different iCloud account that had previously accepted the CKShare. Without sending a new invite, that device found the "Household" zone via allRecordZones() on sharedCloudDatabase — it could pull all 578 records, push updates, and the share URL still resolved.

Meanwhile, the owner device (zone creator) gets "zone not found" from both allRecordZones() and direct recordZone(for:) on privateCloudDatabase.

So it looks like the zone is deleted from the owner's private database, but the CKShare and zone records remain accessible to participants via the shared database. Participants can still read and write as if nothing happened — the owner just can't see the zone anymore.

This also creates a recovery problem — when the owner creates a new zone with the same name, it gets a new CKShare URL, but the participant is still connected to the old "ghost" zone. The two sides are permanently split.

Does this mean the zone deletion is happening through a path that doesn't properly clean up the sharing infrastructure? Is this expected behavior when a zone-wide CKShare's zone is deleted, or does it suggest the deletion is happening through an abnormal server-side path?

What I've ruled out

HypothesisTestResult
publicPermission = .readWriteChanged to .none + explicit addParticipantZone survived longer but still eventually deleted
Zone name tombstoningTested 6 fresh names never used in this containerAll eventually deleted
Non-owner writes causing deletionGated ALL non-owner push methods (recipe, meal plan, grocery, photo, event)Zone still deleted
database.save(share) vs modifyRecordsSwitched to modifyRecords(saving:deleting:)Zone still deleted
NSPersistentCloudKitContainer interferenceRemoved all Core Data CloudKit codeZone still deleted
Double share acceptanceFresh app install, single acceptance onlyZone still deleted
Advanced Data ProtectionNeither account has ADP enabledNot the cause
Programmatic vs system acceptanceTested both container.accept() and tapping share linkZone still deleted

CloudKit Dashboard

No ZoneDelete operation is visible in the logs. All operations are ZoneFetch, ZoneChanges, RecordQuery, RecordFetch. I do see EphemeralGroup operations targeting the custom zone — not sure what generates those.

Comparison with working apps

I compared my implementation with another app that uses the exact same zone-wide CKShare(recordZoneID:) pattern with publicPermission = .readWrite and programmatic acceptance — and it works. The main difference is that app uses CKSyncEngine (iOS 17+) rather than raw CKFetchRecordZoneChangesOperation / CKModifyRecordsOperation. Could CKSyncEngine be handling something internally that prevents this issue?

Questions

  1. Is there a known interaction between zone-wide CKShare(recordZoneID:) acceptance and zone lifecycle that could cause zone deletion?
  2. Does CKSyncEngine handle zone-wide sharing differently than manual CKFetchRecordZoneChangesOperation + CKModifyRecordsOperation?
  3. What generates EphemeralGroup operations in CloudKit Dashboard? Could these trigger a zone delete?
  4. After 20+ zone create/delete cycles in a container, is there a server-side rate limit or tombstone mechanism that would destabilize new zones?
  5. Is the inconsistent state I described (zone gone from owner's private DB but still accessible from participant's shared DB) expected behavior, or does it indicate the deletion is happening through an abnormal path?
  6. Is the custom programmatic acceptance flow (CKFetchShareMetadataOperationcontainer.accept()) fully supported for zone-wide shares, or does it require UICloudSharingController?

Any guidance would be greatly appreciated. This is blocking multi-user functionality for our app (mesa, a meal planning app on the App Store). Single-user sync works perfectly — the issue only manifests when a second iCloud account is involved.

Environment: iOS 18.4.1, Xcode 16+, Swift, SwiftUI

Answered by DTS Engineer in 884621022

Let's follow up with your other post, which I've replied.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Let's follow up with your other post, which I've replied.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

CKRecordZone deleted when second user accepts zone-wide CKShare
 
 
Q