rsync Exit Code 12: Protocol Stream Error in CI
rsync exit code 12 means an error in the rsync protocol data stream, most often a broken or unclean SSH connection.
Code 12 usually means the transport died: a dropped SSH session, a server that prints output before rsync starts, or a killed remote process.
What it does
Exit 12 is "rsync error: error in rsync protocol data stream (code 12)". It fires when the connection between the two rsync processes is corrupted or cut: the SSH link dropped, the remote shell emitted unexpected output, or the remote rsync was killed (often by an out-of-memory event or timeout).
Common causes
| Cause | Typical fix |
|---|---|
| Remote shell prints a banner/motd | Quiet shell startup; see protocol mismatch |
| SSH connection dropped | Add retries; use -P --partial to resume |
| Remote rsync OOM-killed | Reduce parallelism; check server memory |
| Idle timeout closed the session | Set --timeout / SSH ServerAliveInterval |
Common usage
# Add an I/O timeout and resume support to ride out hiccups
rsync -avP --timeout=120 dist/ user@host:/srv/
# Often paired with the protocol-mismatch message:
# rsync: connection unexpectedly closed (0 bytes received so far)
# rsync error: error in rsync protocol data stream (code 12)In CI
If code 12 appears together with "protocol version mismatch -- is your shell clean?", the remote login shell is printing text before rsync runs. Move banners and echo statements out of non-interactive shell startup, or test with "ssh user@host rsync --version" to confirm the channel is clean.
Common errors in CI
rsync: connection unexpectedly closed (0 bytes received so far) [sender]. rsync error: error in rsync protocol data stream (code 12) at io.c. Check that SSH itself works, that known_hosts is set, and that the remote shell is silent. Wrap the deploy in a retry loop with --partial for transient drops.