Troubleshooting and Debugging
When rsync fails or behaves unexpectedly, the key is systematic debugging — not just retrying blindly. Rsync provides excellent diagnostic tools built right into its flags.
Debugging Tools
Increase Verbosity
# Single verbose (shows transferred files)
rsync -av /src/ /dest/
# Double verbose (shows skipped files too)
rsync -avv /src/ /dest/
# Triple verbose (shows full protocol debug)
rsync -avvv /src/ /dest/
Itemize Changes
Shows exactly what changed and why for each file:
rsync -av --itemize-changes /src/ /dest/
Reading the output:
>f.st...... uploads/photo.jpg
>f..t...... config/settings.php
cd+++++++++ new-directory/
*deleting old-file.txt
| Character | Position | Meaning |
|---|---|---|
> | 1 | File sent to remote |
< | 1 | File received from remote |
f | 2 | Regular file |
d | 2 | Directory |
c | 3 | Checksum differs |
s | 4 | Size differs |
t | 5 | Timestamp differs |
p | 6 | Permissions differ |
o | 7 | Owner differs |
g | 8 | Group differs |
Log to File
rsync -av --log-file=/var/log/rsync/debug.log /src/ /dest/
Debug SSH Connection
rsync -av -e "ssh -v" /src/ user@remote:/dest/
Common Errors and Fixes
Permission Denied
rsync: mkstemp "/dest/.file.XXXXXX" failed: Permission denied (13)
Causes and fixes:
# Wrong ownership on destination
sudo chown -R $USER:$USER /dest/
# Wrong permissions on destination
sudo chmod 755 /dest/
# Running as wrong user
sudo -u www-data rsync -av /src/ /dest/
SSH Connection Issues
rsync: connection unexpectedly closed
ssh: connect to host server port 22: Connection refused
# Test SSH separately
ssh -v user@server
# Check SSH service
sudo systemctl status sshd
# Check firewall
sudo ufw status
# Use specific key
rsync -av -e "ssh -i ~/.ssh/specific_key" /src/ user@server:/dest/
# Use non-standard port
rsync -av -e "ssh -p 2222" /src/ user@server:/dest/
Disk Full
rsync: write failed on "/dest/file": No space left on device (28)
# Check disk space
df -h /dest/
# Clean old backups
find /dest/ -maxdepth 1 -type d -name "20*" -mtime +14 -exec rm -rf {} \;
# Check for large files consuming space
du -sh /dest/* | sort -hr | head -20
Broken Pipe / Connection Reset
rsync error: unexplained error (code 255)
rsync: connection unexpectedly closed (0 bytes received so far)
# Resume interrupted transfer
rsync -avP --partial /src/ user@remote:/dest/
# Increase timeout for slow connections
rsync -av --timeout=120 /src/ user@remote:/dest/
# Use SSH keepalive
rsync -av -e "ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=5" \
/src/ user@remote:/dest/
Files Vanished
rsync warning: some files vanished before they could be transferred (code 24)
This is usually harmless — temporary files (cache, session files, log rotations) disappeared between scan and transfer:
# Exclude volatile directories to prevent this
rsync -av \
--exclude='cache/' \
--exclude='tmp/' \
--exclude='sessions/' \
/src/ /dest/
Checksum Mismatch
# Force checksum verification
rsync -avc /src/ /dest/
# If files keep showing as different, check if they're being
# modified during transfer
lsof +D /src/ # List open files in source
Debugging Workflow
flowchart TD
FAIL["rsync failed"] --> CODE["Check exit code ($?)"]
CODE --> |"0"| OK["Success "]
CODE --> |"1-5"| SYNTAX["Fix command syntax or paths"]
CODE --> |"10-12"| NET["Network issue — check SSH, firewall"]
CODE --> |"23"| PARTIAL["Partial transfer — check permissions, disk space"]
CODE --> |"24"| VANISH["Files vanished — usually harmless"]
CODE --> |"30"| TIMEOUT["Timeout — increase --timeout"]
CODE --> |"255"| SSH["SSH error — debug with ssh -v"]
NET --> RETRY["Retry with -P --partial"]
PARTIAL --> PERMS["Fix permissions, check disk"]
TIMEOUT --> RETRY
SSH --> SSHFIX["Check keys, port, firewall"]
Performance Debugging
When rsync is slow rather than broken:
# Add --stats to see transfer efficiency
rsync -avz --stats /src/ user@remote:/dest/
Key metrics to watch:
| Metric | What It Tells You |
|---|---|
| Total file size | How much data exists |
| Total transferred file size | How much actually sent |
| Speedup | Higher = better delta compression |
| Number of files transferred | How many files changed |
# Monitor system resources during transfer
htop # CPU usage (compression overhead?)
iotop # Disk I/O (scanning bottleneck?)
nload # Network (bandwidth saturation?)
Common Pitfalls
| Pitfall | Consequence | Prevention |
|---|---|---|
| Retrying without checking exit code | Same failure repeats | Always check $? first |
| Missing trailing slash on source | Creates nested directory | /src/ copies contents, /src copies the directory itself |
root rsync without --chown | Files owned by root on destination | Use --chown=www-data:www-data |
| No logging for cron jobs | Can't debug failures after the fact | Always use --log-file |
| Ignoring exit code 23 | Missed permission errors assumed harmless | Review log for which files failed |
Quick Reference
# Verbose debugging
rsync -avvv /src/ /dest/
# Itemize all changes
rsync -av --itemize-changes /src/ /dest/
# Log to file
rsync -av --log-file=/var/log/rsync/debug.log /src/ /dest/
# Debug SSH
rsync -av -e "ssh -v" /src/ user@remote:/dest/
# Resume interrupted transfer
rsync -avP --partial /src/ /dest/
# Dry run to preview without changing anything
rsync -avn --itemize-changes /src/ /dest/
What's Next
- Exit Codes and Error Handling — Build scripts that handle failures
- Compatibility Issues — Cross-platform troubleshooting
- Dry Run and Testing — Preview before executing