Skip to content

The macOS’ version of the cp Unix command won’t create links

Update: Apple fixed this in macOS 14.4; the cp command can once again create hard links.

I ran into this while working on a Keyboard Maestro macro that creates hard links: The macOS version of cp won't create links, at least not in Sonoma. In Ventura, it works even though it throws the same error as it does in Sonoma.

Copying as hard links is part of the cp feature set, fully covered in its man pages. But it doesn't work in macOS. To confirm, try this:

When I ran into this, I searched and discovered that someone else had run into the same issue,1Apple Developer login required but that's the only mention I could find.

I have filed this bug as FB13255408 with Apple, and I'm hopeful they fix it soon. There is a workaround, obviously: Use ln instead. This works fine for individual hard links, but using cp to quickly copy an entire folder as hard links is a nicer implementation.

5 thoughts on “The macOS’ version of the cp Unix command won’t create links”

  1. I believe “hard links” in apfs just symbolic links? I thought I had read that apfs doesn’t support hard links. I think ln is the appropriate resolution and creating symbolic links. I can’t find the reference at the moment. I will try and dig it up.

  2. On an APFS drive, there's still a difference between a symbolic link and a hard link:

    The first number is the file's inode, and for the hard link, it's identical to the original file1.txt. The hard link was created with ln. The second file is a symbolic link, created with ln -s, and it has a new inode, indicating it's not a hard link.

    The issue doesn't seem to be hard links in general, rather that cp -al doesn't create hard links when its documentation says it should, and it used to do so.


  3. Hard linked directories in HFS+ existed due to the requirements of Time Machine. Unix explicitly does not allow for hard linked directories because it can lead to circular dependencies that will cause a mess.

    This is just broken, and I suspect it is because the Apple implementation was not updated to handle some APFS or SIP-related changes. If you use Homebrew and install the GNU-based cp (via coreutils) it works fine without any errors. Unfortunately, the Apple provided utilities often work enough for Apple's use cases and that's all they can be trusted to do. They are unreliable, questionably maintained and often randomly broken (grep is also broken in Sonoma).

    Having said that, if it is necessary to rely on what you know is on any machine, there are various workarounds beyond ln…you can certainly find ways to use rsync which should have too much of a performance hit or be too wasteful given the nature of the operation (/usr/bin/rsync -r --link-dest=test test/ test2). But ther is no doubt that this feels more than a little ridiculous for such a core utility misbehaving.

Leave a Reply

Your email address will not be published. Required fields are marked *