Why your Mac may struggle to update XProtect

XProtect is the front line of macOS’s defence against malware. Run as part of Gatekeeper’s checks, it scans apps and other executable code against a huge list of rules, aiming to detect anything known to be malicious. Apple updates it most weeks, to augment and realign its detection rules to ensure they remain effective, and all reasonably modern Macs should install those updates within 24 hours of their release.

Second copy

Over two years ago, in macOS 15 Sequoia, Apple improved XProtect by relocating the primary copy of its rules to a new directory in /var/protected, and changing the mechanism for updating it there. Since then, all Macs running Sequoia and later have used the XProtect.bundle in /var/protected/xprotect as their primary source of those rules, while still maintaining the copy in their old location in /Library/Apple/System/Library/CoreServices. As a result, those Macs should update the new primary location using a connection to iCloud, and their original and now secondary location using the traditional Software Update service.

To assist with maintaining the new primary location, macOS has a command tool that can be used to check the version number installed, check the current version available from iCloud, and force the new primary location to be updated when necessary: xprotect.. Since its introduction that command tool has varied in its abilities. At some times, it has been able to convert a copy of XProtect installed in the secondary location, and use that to update its primary copy using the secondary obtained by Software Update. But at other times that hasn’t worked and the only means of updating the primary location has been for it to obtain the update from iCloud. As that has changed without notice, documentation or explanation, it has left many users confused.

Command tool

The xprotect command tool has three relevant options:

  • xprotect version returns the version currently installed in the primary location;
  • sudo xprotect check returns the version currently available from iCloud;
  • sudo xprotect update downloads any version more recent than that currently installed in the primary location, from iCloud, and installs it in the primary location. However, it will not normally use an updated copy in the secondary location to update that in the primary location.

Current status

As of 3 November 2026:

  • macOS Golden Gate 27.0-27.2 – all three xprotect commands work as expected.
  • macOS Tahoe 26.x-26.7.2 – all three xprotect commands work as expected.
  • macOS Sequoia 15.8-15.8.2 – only xprotect version works as expected. xprotect check consistently returns Got error checking for update: Error Domain=XProtectUpdateError Code=11 "(null)". xprotect update consistently reports that no update is available, even when one is.
  • macOS Sequoia 15.6.1 – all three xprotect commands work as expected.

The error on running the check option prevailed during the beta-test phase of Golden Gate, and early after the public release of 27.0, but then disappeared.

The end result is that those running versions of Sequoia that are kept up to date with security updates are unable to use the xprotect command to update XProtect. However, a periodic background service XProtectUpdateService appears able to use an updated secondary copy to update the primary location. That can take a day or more before it occurs spontaneously, and can’t be forced using xprotect update.

Cause of failure in Sequoia

Comparing log entries obtained from VMs running 15.6.1, 15.8, 26.7.2 and 27.2, the most obvious differences arise in responses from the iCloud server, which consistently returns an error 48, and failure to “fetch some records”, although those are reported differently to the user depending on whether it was a check or update that failed.

Example entries are:
1.092498 com.apple.cloudkit req: 277313FE-299D-4EE3-AF21-26E97D6DA23C, "Received error 48 from the server: [private]"
1.092500 com.apple.cloudkit req: 277313FE-299D-4EE3-AF21-26E97D6DA23C, "Node level failure encountered while parsing"
1.094429 com.apple.cloudkit Calling completion block for nil or failed record with ID <CKRecordID: 0x520ade120; recordName=current, zoneID=audience_macOS_15_8:__defaultOwner__>: Error Domain=CKInternalErrorDomain Code=2036 UserInfo={ContainerID=[private], OperationID=[private], RequestUUID=[private], errorKey=[private], ServerErrorDescription=[private], CKErrorDescription=[private], NSLocalizedDescription=[private]}
1.095950 com.apple.security.XProtectFramework.XProtectUpdateService Received CloudKit error when resolving record IDs to records: [private]
1.097114 com.apple.cloudkit Finished operation <CKFetchRecordsOperation: 0x104f33790; databaseScope=Public, operationID=DB9832B247B1CFCB, resolvedConfig={ timeoutForRequest=60, timeoutForResource=300, flags=preferAnon }, qos=Utility, stateFlags=executing, [private]> with error: <CKUnderlyingError 0xa34018f90: "PartialFailure" (1011); "Failed to fetch some records"; partial errors: {
current:(audience_macOS_15_8:__defaultOwner__) = <CKError 0xa34018e70: "Zone Not Found" (26/2036); server message = "Zone does not exist"; op = DB9832B247B1CFCB; uuid = 277313FE-299D-4EE3-AF21-26E97D6DA23C>}>
1.097166 com.apple.security.XProtectFramework.XProtectUpdateService Propagating returned error: Failed to resolve record IDs to records.
1.097175 com.apple.security.XProtectFramework.XProtectUpdateService No update returned
1.097178 com.apple.cloudkit Operation DB9832B247B1CFCB finished with error: <CKUnderlyingError 0xa34018f90: "PartialFailure" (1011); "Failed to fetch some records"; partial errors: { current:(audience_macOS_15_8:__defaultOwner__) = <CKError 0xa34018e70: "Zone Not Found" (26/2036); server message = "Zone does not exist"; op = DB9832B247B1CFCB; uuid = 277313FE-299D-4EE3-AF21-26E97D6DA23C>}> Error Domain=CKErrorDomain Code=2 UserInfo={ContainerID=[private], NSDebugDescription=[private], CKPartialErrors=[private], RequestUUID=[private], NSLocalizedDescription=[private], CKErrorDescription=[private], NSUnderlyingError=0xa34018f90 {Error Domain=CKInternalErrorDomain Code=1011 UserInfo={CKErrorDescription=[private], NSLocalizedDescription=[private], CKPartialErrors=[private]}}}

Conclusions

A persistent bug is currently preventing updated versions of macOS Sequoia from updating XProtect in its primary location. Indications are that this may be occurring in iCloud servers rather than in local macOS.

If your Mac is running macOS Sequoia:

  • Utilities like SilentKnight will still alert you to XProtect updates when they are released.
  • Use SilentKnight or softwareupdate to download and install the version made available to your Mac’s secondary location.
  • Hope that at some time in the coming days XProtectUpdateService will run automatically on your Mac, and use the copy of XProtect in its secondary location to install that to its primary location.
  • There is no point in trying to use xprotect to check or update XProtect in its primary location until this bug is fixed.

This doesn’t appear to affect macOS Tahoe or Golden Gate, in which xprotect should behave as intended, and described above.