Which extended attributes does macOS Tahoe preserve?
Extended attributes (xattr) contain a wide range of metadata, some of which are intended to persist with the file they’re attached to, others to be more transient. Depending on the type of file operation performed, macOS has an elaborate mechanism for determining which are preserved, and which are not. This article tries to explain how this works in macOS Tahoe 26.0.
Xattr flags
When first introduced in Mac OS X, no provision was made for xattrs to have type-specific preservation, and that was added later using flags suffixed to the xattr’s name. For example, the com.apple.lastuseddate xattr found commonly on edited files is shown with a full name of com.apple.lastuseddate#PS to assign the two flags P and S to it, and the most recent xattr com.apple.fileprovider.pinned, used to mark files in iCloud Drive that have been pinned, has the two flags P and X assigned to it for a the full name of com.apple.fileprovider.pinned#PX.
![]()
This is a kludge, because you normally have to refer to the xattr name including its flags, although the flags aren’t really part of its name. This can catch the unwary.
It’s further complicated by a set of system tables for some standard xattr types that don’t have flags suffixed, but are treated as if they do. One notable example of those is the quarantine xattr com.apple.quarantine, which is handled by macOS as if it has the PCS flags attached, although those are never used when referring to it by name.
There are also lower case flags that can be used to override those set in system tables, although those appear to be used exceedingly rarely, and I don’t recall ever coming across them. In theory, if you were using a new type based on the standard com.apple.metadata: family, com.apple.metadata:kMDItemNew, you could alter its behaviour to some similar types with the flags psB, as in com.apple.metadata:kMDItemNew#psB. I have no idea whether that would be respected in practice. For the rest of this article, I will ignore the existence of those lower case flags.
Intents
File operations involving decisions about the preservation of xattrs are simplified into the following intents:
- copy – simply copying a file from a source to a destination and preserving its data, such as using
cp, is labelledXATTR_OPERATION_INTENT_COPY - save – saving a file when probably changing its content, including performing a ‘safe save’; this may over-write or replace the source with the saved file. Some xattrs shouldn’t be preserved in this process of
XATTR_OPERATION_INTENT_SAVE - share – sharing or exporting this file, perhaps as an attachment to email, or placing the file in a public folder. Some sensitive metadata shouldn’t be preserved in
XATTR_OPERATION_INTENT_SHARE - sync – syncing the file to a service such as iCloud Drive, in
XATTR_OPERATION_INTENT_SYNC - backup – backing the file up, perhaps using Time Machine, in
XATTR_OPERATION_INTENT_BACKUP.
Flags
As of macOS 15.0 (including 26.0), the following flags are supported:
- C:
XATTR_FLAG_CONTENT_DEPENDENTties the flag with the file contents, so the xattr has to be recreated when the file data changes. This may be appropriate for checksums and hashes, text encoding, and position information. The xattr is then preserved for copy and share, but not in a safe save. - P:
XATTR_FLAG_NO_EXPORTdoesn’t export or share the xattr, but preserves it during copying. - N:
XATTR_FLAG_NEVER_PRESERVEensures the xattr is never preserved, even when copying the file. - S:
XATTR_FLAG_SYNCABLEensures the xattr is preserved during syncing with services such as iCloud Drive. Default behaviour is for xattrs to be stripped during syncing, to minimise the amount of data to be transferred, but this flag overrides that. - B:
XATTR_FLAG_ONLY_BACKUPkeeps the xattr only in backups, including Time Machine, where there’s no desire to minimise what’s backed up. - X:
XATTR_FLAG_ONLY_SAVINGkeeps the xattr only when saving and in backups, including Time Machine (macOS 15.0 and later only).
There’s another system limit that must be adhered to: total length of the xattr name including any # and flags cannot exceed a maximum of 127 UTF-8 characters.
System tables
These are hard-coded in source, where * represents a ‘wild card’:
com.apple.quarantine– PCS preserved in copy, sync, backupcom.apple.TextEncoding– CS copy, share, sync, backupcom.apple.metadata:kMDItemCollaborationIdentifier– B backupcom.apple.metadata:kMDItemIsShared– B backupcom.apple.metadata:kMDItemSharedItemCurrentUserRole– B backupcom.apple.metadata:kMDItemOwnerName– B backupcom.apple.metadata:kMDItemFavoriteRank– B backupcom.apple.metadata:*(except those above) – PS copy, save, sync, backupcom.apple.security.*– S or N depending on sandboxing, see belowcom.apple.ResourceFork– PCS copy, sync, backupcom.apple.FinderInfo– PCS copy, sync, backupcom.apple.root.installed– PC copy, backup.
System defaults for com.apple.security.* depend on whether the app performing the file operation is running in an app sandbox. Non-sandboxed apps apply S to preserve the xattr for copy, save, share, sync, backup; for sandboxed apps N is applied so the xattr is never preserved, even when copying the file.
Flags and intents
We can now revisit the list of intents, and establish the effects of xattr flags on each, as:
XATTR_OPERATION_INTENT_COPYpreserves xattrs that don’t have flag N or B or XXATTR_OPERATION_INTENT_SAVEpreserves xattrs that don’t have flag C or N or BXATTR_OPERATION_INTENT_SHAREpreserves xattrs that don’t have flag P or N or B or XXATTR_OPERATION_INTENT_SYNCpreserves xattrs if they have flag S, or have neither N nor BXATTR_OPERATION_INTENT_BACKUPpreserves xattrs that don’t have flag N.
Finally, Apple provides separate information on how xattrs are synced by FileProvider, for iCloud Drive and third-party cloud services using that API. This confirms that the S flag should sync a xattr, but is vague on other flags, simply stating “some older attributes are also synced”. However, a cap is applied on the maximum size of xattrs that are syncable, at “about 32KiB total for each item”. If the xattrs exceed that limit “the system automatically makes some of the attributes nonsyncable.” More puzzlingly, it states “the resource fork is content and isn’t included in the extended attributes dictionary.”
Conclusions
- Controls over the preservation of xattrs are appended as tags to their name, following a hash #. In most circumstances, they should be treated as part of that xattr’s name, and are required for commands and actions on that xattr, for example when using the
xattrcommand. They should also be left intact and not removed, unless you want to change the behaviour of that xattr in file operations. - Most xattrs commonly used by macOS don’t explicitly use tags, but are governed by a hard-coded system table that can’t be changed.
- When using standard commands such as
cp, macOS will automatically apply these rules when deciding whether to preserve xattrs. However, using a command for a different intent, such ascpfor backing up, won’t normally invoke the behaviour you might want. - Code using standard macOS file operations should follow the behaviour expected for its intent, and shouldn’t require any special handling of xattrs. Lower-level operations are likely to differ, though, and may require implementation of equivalent behaviours.
- Those implementing their own xattr types should incorporate flags explicitly to ensure they’re preserved as intended.
- In cases of uncertainty, for example when working with files stored in iCloud Drive, you’ll need to step carefully through the rules above.
Sources
xattr_flags.h, xattr_flags.c, xattr_properties.h in copyfile source, e.g. at Apple’s OSS Distributions Github
man xattr_name_with_flags(3), included in copyfile source
FileProvider (Apple).
















