When working across different Unix systems, I recently encountered a frustrating rsync error during file transfers between:
- Local: Ubuntu 10.04 (rsync 3.0.7)
- Remote: FreeBSD 6.4 (rsync 2.6.8)
# Error during pull operation
receiving file list ... Invalid flist flag: 1004
rsync error: protocol incompatibility (code 2) at flist.c(2354) [Receiver=3.0.7]
The core issue stems from protocol version mismatch. Rsync 2.6.8 uses protocol 29 while 3.0.7 uses protocol 30. The -a (archive) flag attempts to use newer features unavailable in v2.6.8.
Key findings from testing:
- Error persists with -a but disappears with -rlpt
- Adding --no-whole-file triggers different protocol errors
- Problem occurs bidirectionally (push/pull)
Option 1: Downgrade rsync flags
rsync -rlptv -e ssh --delete username@server:/remote/path/ /local/path
Option 2: Protocol version forcing
rsync --protocol=29 -av -e ssh username@server:/remote/path/ /local/path
Option 3: Update rsync versions
# On FreeBSD (remote)
pkg_add -r rsync3
# Verify version
rsync --version | head -1
For environments where upgrading isn't possible:
# Use tar over ssh as fallback
ssh username@server "cd /remote/path && tar czf - ." | tar xzvf - -C /local/path
# Alternative using rsync module syntax
rsync -z --rsh=ssh --protocol=29 username@server::module/path /local/path
Rsync Version | Protocol | Compatible With |
---|---|---|
2.6.8 | 29 | 3.0.x (with --protocol=29) |
3.0.7 | 30 | 3.1.x (backward compatible) |
Remember that newer rsync versions typically maintain backward compatibility better than older versions support forward compatibility.
When working across different Unix systems with varying rsync versions, protocol incompatibility errors like Invalid flist flag: 1004
can halt your synchronization workflows. Here's what's happening under the hood:
# Error breakdown:
[Receiver=3.0.7] fails to parse protocol elements from [sender=2.6.8]
Flag 1004 represents extended attribute transfer (xattrs) - introduced in v3.0.0
Option 1: Downgrade protocol features (temporary fix)
rsync -av --no-xattrs -e ssh user@remote:/path/ /local/path
# Or more comprehensively:
rsync -rlptgoDv --no-xattrs --no-perms --no-owner --no-group -e ssh user@remote:/path/ /local/path
Option 2: Version alignment (permanent solution)
# On FreeBSD (remote):
pkg_add -r rsync30 # For FreeBSD 6.x
# Or compile from source:
wget https://download.samba.org/pub/rsync/src/rsync-3.0.9.tar.gz
tar xzf rsync-3.0.9.tar.gz
cd rsync-3.0.9
./configure --prefix=/usr/local
make && make install
When immediate upgrade isn't possible, force protocol version 29:
rsync --protocol=29 -av -e ssh user@remote:/path/ /local/path
Important caveats when forcing protocol 29:
- Loses xattr support (ACLs/SELinux contexts)
- May not preserve all timestamp precision
- Some newer checksum algorithms won't be available
For environments where upgrading isn't feasible, consider Docker-based rsync:
# Local machine (using modern rsync in container):
docker run --rm -v /local/path:/data alpine rsync -av --protocol=29 user@remote:/path/ /data
# Remote machine (if you can install Docker):
docker run --rm -v /remote/path:/data alpine rsync -av --protocol=29 /data/ user@local:/path/
For scripts that need to handle mixed environments:
#!/bin/bash
REMOTE_RSYNC_VER=$(ssh user@remote "rsync --version | head -1 | awk '{print \$3}'")
if [[ "$REMOTE_RSYNC_VER" < "3.0.0" ]]; then
RSYNC_OPTS="--protocol=29 --no-xattrs"
else
RSYNC_OPTS="-aX"
fi
rsync $RSYNC_OPTS -e ssh user@remote:/path/ /local/path