Troubleshooting Linux rsync ‘Operation Not Permitted’ & Code 23 Errors from macOS
Resolve common 'rsync: some files could not be transferred permissions' errors when syncing from macOS to Linux, often caused by destination server permission issues or incorrect rsync flags like -a.
Resolve common 'rsync: some files could not be transferred permissions' errors when syncing from macOS to Linux, often caused by destination server permission issues or incorrect rsync flags like -a.
When synchronizing files from your macOS development environment to a remote Linux server using rsync over SSH, encountering permission-related errors is a common hurdle for many system administrators and developers. These errors typically manifest as Operation not permitted messages followed by rsync error: some files/attrs could not be transferred (code 23). This guide provides a highly technical, accurate, and step-by-step approach to diagnose and resolve these persistent rsync permission issues.
Symptom & Error Signature
You are attempting to push files from your local macOS machine to a remote Linux server using rsync, often with the -a (archive) flag. The command might look something like this:
rsync -avz --exclude '.DS_Store' -e "ssh -p 22" /path/to/local/project/ [email protected]:/var/www/html/project/
During the transfer, rsync fails to set file attributes (permissions, ownership, group) on the remote server for some files or directories, displaying errors similar to these:
sending incremental file list
...
rsync: [sender] chgrp "file.txt" failed: Operation not permitted (1)
rsync: [sender] chmod "directory/subdirectory/" failed: Operation not permitted (1)
rsync: [sender] chown "another_file.php" failed: Operation not permitted (1)
rsync error: some files/attrs could not be transferred (code 23) at main.c(1820) [sender=3.2.7]
The specific code 23 indicates that "some files/attrs could not be transferred," often due to permission problems.
Root Cause Analysis
The rsync permission errors, specifically Operation not permitted (code 1) leading to code 23, almost universally point to a mismatch between the desired file attributes (permissions, ownership, group) you're trying to set from your macOS machine and what the SSH user on the remote Linux server is actually allowed to do.
The primary culprits are usually:
- Insufficient Permissions on Remote Target Directory: The SSH user (
userin[email protected]) does not have write permissions to the destination directory (/var/www/html/project/) on the Linux server. This is the most basic and common issue. rsync -a(Archive Mode) Implications: The-aflag is a powerful shortcut for-rlptgoD(recursive, links, permissions, times, group, owner, devices/specials). Whenrsyncattempts to preserveowner(-o) andgroup(-g) on the remote server, it will fail if the SSH user:- Is not
root. - Does not own the target directory.
- Is not a member of the target group.
- Does not have the necessary
CAP_CHOWNorCAP_SETGIDcapabilities. Normal users on Linux cannot arbitrarilychownfiles to other users orchgrpfiles to groups they are not part of.
- Is not
- Inability to Preserve Permissions (
-p): While less common to fail entirely, preserving explicit permission bits (chmod) can also be problematic if the user doesn't own the file or if the remote filesystem/directory has restrictiveumasksettings or Access Control Lists (ACLs) that prevent the user from setting specific permissions. - SELinux/AppArmor Context Restrictions: On systems with mandatory access control frameworks like SELinux (Red Hat-based) or AppArmor (Debian/Ubuntu), even if file system permissions seem correct, the security context might prevent the
rsyncprocess (running as your SSH user) from writing to or modifying files in certain locations. - Immutable Bits: Less frequently,
chattr +i(immutable bit) could be set on files or directories on the remote, preventing any modification, even by root.
Step-by-Step Resolution
Follow these steps to systematically diagnose and resolve the rsync permission errors.
1. Verify and Correct Remote Destination Directory Permissions
This is the most critical first step. Ensure the SSH user has appropriate write permissions to the target directory and its contents on the Linux server.
Connect to your Remote Server:
ssh [email protected]Check Current Permissions and Ownership: Replace
/var/www/html/project/with your actual destination path.ls -ld /var/www/html/project/ ls -la /var/www/html/project/ # To see contents and their ownership whoami # To confirm the user you are logged in asPay close attention to the
owner:groupand the permission bits (e.g.,drwxr-xr-x). Thewhoamioutput should match the owner of the directory, or at least theusershould be in thegroupthat has write permissions.Adjust Ownership and Permissions (if necessary): If the SSH user (
user) does not own the directory or doesn't have write permissions, you'll need to correct it.Carefully choose the correct owner, group, and permissions. Misconfiguring these can lead to security vulnerabilities or make your web server unable to read/write files. For web content,
www-data(Ubuntu/Debian) ornginx/apache(other distros) is a common web server user.To change ownership and group (e.g., to your SSH user and
www-datagroup, which your user might be a part of):sudo chown -R user:www-data /var/www/html/project/To ensure the owner has full read/write/execute and the group has read/execute:
sudo chmod -R u=rwX,g=rX /var/www/html/project/The
Xinchmodallows execute permission only if the file is a directory or already has execute permission for some user. This is generally good practice to avoid making all files executable. If you need group write access for collaborative development, you might useg=rwX.After changing permissions, you might want to add your
userto thewww-datagroup:sudo usermod -aG www-data user. You'll need to log out and back in for group changes to take effect.
2. Adjust rsync Flags for Permission Handling
If the remote permissions are set correctly, the issue is likely rsync trying to set ownership/group that your SSH user cannot.
Exclude Ownership and Group Preservation: The most common fix is to tell
rsyncnot to preserve owner (-o) and group (-g) when using archive mode (-a). This way, files will be created with the ownership and group of the SSH user on the remote server.rsync -avz --exclude '.DS_Store' --no-o --no-g -e "ssh -p 22" /path/to/local/project/ [email protected]:/var/www/html/project/This command will preserve permissions (
-p) but create files owned byuser:user(oruser:primary_group_of_user) on the remote, which is typically what's desired ifuserhas write access to the destination.Explicitly Set Remote Ownership/Group (Alternative): If you need files on the remote to have a specific owner and group, you can use the
--chownflag. This requires theuseron the remote to have the necessary permissions (e.g.,sudoaccess, which we'll cover later, or for the target owner/group to already be the SSH user's).rsync -avz --exclude '.DS_Store' --chown=www-data:www-data -e "ssh -p 22" /path/to/local/project/ [email protected]:/var/www/html/project/The
--chownflag typically requiresrootprivileges on the destination for non-self-owned files. If your SSHuseris notroot, this will likely fail unlessuseris implicitly allowed to chown towww-data:www-data(which is highly unusual). In most scenarios,--no-o --no-gis safer and more effective.
3. Bypass Permissions with sudo on Remote (Advanced)
If you absolutely need rsync to preserve all attributes and your remote user has password-less sudo access (or you're willing to provide a password), you can instruct rsync to execute as root on the remote side.
Using
sudowithrsyncon the remote side is a powerful operation. Ensure you fully trust the source and destination paths. Granting a user password-lesssudoforrsyncis a significant security risk and should only be done if strictly necessary and understood.
Configure
sudo(if not already): On the remote server, edit yoursudoersfile (sudo visudo) to allow theuserto runrsyncwithout a password.user ALL=(ALL) NOPASSWD: /usr/bin/rsyncOr, more restrictively:
user ALL=(ALL) NOPASSWD: /usr/bin/rsync --server *The latter is more secure as it only allows the server-side component of rsync.
Execute
rsyncwithsudo: From your macOS machine:rsync -avz --exclude '.DS_Store' -e "ssh -p 22" --rsync-path="sudo rsync" /path/to/local/project/ [email protected]:/var/www/html/project/This tells
rsyncto prependsudoto thersynccommand executed on the remote, allowing it to perform privileged operations like changing ownership and group.
4. Check SELinux/AppArmor Status (Remote)
If you're still facing issues after addressing file permissions and rsync flags, particularly on CentOS/RHEL (SELinux) or Ubuntu/Debian (AppArmor), these security modules might be blocking operations.
Check SELinux Status (on remote CentOS/RHEL):
getenforce sestatusIf
getenforcereturnsEnforcing, SELinux is active. Look for denials in the audit log:sudo ausearch -c rsync --raw | audit2allow -M rsync_local sudo cat /var/log/audit/audit.log | grep rsync sudo journalctl -xe | grep "SELinux"Temporarily setting SELinux to
Permissivecan help diagnose:sudo setenforce 0. Ifrsyncworks, you'll need to create proper SELinux policies or label the directory correctly (chcon).Check AppArmor Status (on remote Ubuntu/Debian):
sudo aa-status sudo dmesg | grep "apparmor" sudo journalctl -xe | grep "apparmor"If AppArmor is enforcing a profile that restricts
rsyncor the target directory, you might see denials indmesgorjournalctl. You could temporarily disable the profile for diagnostic purposes:sudo aa-disable /etc/apparmor.d/path.to.profile.
5. Verify Remote Disk Space
While not directly a permission error, a full disk can sometimes lead to write failures that manifest misleadingly.
- Check Disk Usage (on remote):
Ensure there is sufficient free space on the partition where your destination directory resides. If the disk is full, you'll need to free up space or expand the filesystem.df -h /var/www/html/project/
By systematically applying these troubleshooting steps, you should be able to identify and resolve the rsync permission issues when transferring files from macOS to your Linux server, ensuring smooth and reliable deployments.
Our Production Verification Guarantee
Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.