When transferring files via SCP over VPN, many developers encounter mysterious stalls where the transfer suddenly stops progressing. The debug output typically shows repeated rcvd adjust
messages without actual data transfer:
debug2: channel 0: rcvd adjust 131072
debug2: channel 0: rcvd adjust 131072
From my experience working with remote servers, these are the most frequent culprits:
- VPN connection instability or MTU issues
- TCP window scaling problems
- SSH connection keepalive timeout
- Network congestion control algorithms
Here are the most effective fixes I've found through trial and error:
1. Adjust SSH Configuration
Add these parameters to your /etc/ssh/ssh_config
or ~/.ssh/config
:
Host *
ServerAliveInterval 60
TCPKeepAlive yes
Compression no
IPQoS throughput
2. Use Alternative Transfer Methods
When SCP fails consistently, consider these alternatives:
Rsync with partial transfers:
rsync -avz --partial --progress -e ssh user@remote:/path/to/files /local/path
Tar over SSH:
ssh user@remote "tar czf - /path/to/files" | tar xzvf - -C /local/path
3. Network-Level Optimizations
Try adjusting MTU size and TCP parameters:
# Set MTU (adjust size based on your VPN)
ifconfig eth0 mtu 1400
# Optimize TCP stack
sysctl -w net.ipv4.tcp_window_scaling=1
sysctl -w net.ipv4.tcp_sack=1
For scheduled nightly transfers, implement a retry mechanism:
#!/bin/bash
MAX_RETRIES=3
RETRY_DELAY=60
for ((i=1; i<=$MAX_RETRIES; i++)); do
scp -o ConnectTimeout=30 -o ServerAliveInterval=60 user@remote:/remote/path /local/path
if [ $? -eq 0 ]; then
echo "Transfer completed successfully"
exit 0
fi
echo "Attempt $i failed, retrying in $RETRY_DELAY seconds..."
sleep $RETRY_DELAY
done
echo "All transfer attempts failed"
exit 1
Implement proper logging to diagnose persistent issues:
{
"timestamp": "$(date +%Y-%m-%dT%H:%M:%S)",
"transfer_size": "$(du -sh /local/path | cut -f1)",
"duration": "$SECONDS seconds",
"status": "$([ $? -eq 0 ] && echo "success" || echo "failed")",
"network_stats": "$(ping -c 4 remote.server | grep 'packet loss')"
}
When transferring small to medium-sized files (typically tens of megabytes) via SCP over VPN connections, many administrators encounter unexplained stalls. The transfer begins normally but halts after a few seconds, showing repeated debug messages about channel adjustments:
debug2: channel 0: rcvd adjust 131072
debug2: channel 0: rcvd adjust 131072
The "rcvd adjust" messages indicate SSH flow control adjustments where the receiving end is trying to throttle the data flow. This typically happens when there's:
- Network latency spikes
- VPN packet fragmentation issues
- MTU mismatches
- TCP window scaling problems
Here are proven solutions ranked by effectiveness:
# Solution 1: Use rsync with compression and partial transfers
rsync -avz --partial --progress /local/path/ user@remote:/remote/path/
# Solution 2: Force SCP to use older cipher
scp -c aes128-cbc -oIPQoS=throughput file.txt user@host:/path/
# Solution 3: Adjust TCP parameters
echo "net.ipv4.tcp_window_scaling = 0" >> /etc/sysctl.conf
sysctl -p
For persistent cases, modify your SSH config:
Host *
IPQoS throughput
ServerAliveInterval 60
Compression yes
Ciphers aes128-ctr,aes192-ctr,aes256-ctr
MACs hmac-sha1
If you're using OpenVPN, add these to your config:
tun-mtu 1500
mssfix 1460
fragment 0
link-mtu 1500
When SCP simply won't cooperate:
# Using lftp for resilient transfers
lftp -e "mirror -R /local/path /remote/path" sftp://user:password@host
# Using tar over ssh
tar czf - /local/path | ssh user@host "tar xzf - -C /remote/path"