Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk10 min

How to Fix Rsync “Connection Unexpectedly Closed” Errors

Rsync’s “connection unexpectedly closed” message means the remote protocol process disappeared. This guide shows how to separate SSH shell contamination, missing executables, daemon policy errors, idle timeouts and server crashes.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“Connection unexpectedly closed” means your local rsync lost its connection to the remote rsync process. It is a symptom, not a single diagnosis. The remote process may never have started, a login shell may have written text into rsync’s protocol stream, a daemon may have rejected an option, the network may have timed out, or the remote process may have crashed.

Identify the transport (SSH/remote shell or rsync daemon), capture the exit code, and test the failing layer in that order. The workflow below separates those causes without treating every code 12 failure as an SSH problem.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Start with the transport and the complete error

Save the exact command, all output, and the versions on both ends before changing anything. Rsync has two fundamentally different connection families:

Command form Transport First place to investigate
host:path, commonly with -e ssh or the default remote shell SSH or another remote-shell program starts rsync on the other host The shell session, remote executable, account permissions, and source or destination path
host::module Direct connection to an rsync daemon and a named module Daemon access controls, module settings, option parsing, and daemon logs
rsync://host/module Direct rsync-daemon protocol The same daemon-side checks as host::module

Do not apply an SSH-shell fix to a daemon connection, or diagnose daemon logs when the command is actually launching rsync through SSH. The syntax in the command tells you which branch to follow.

What the message and exit codes actually tell you

The Rsync Project describes the message this way: the local rsync was communicating with a remote rsync process, and that connection is now gone. The same event can be printed as a broken-pipe write or as rsync error: error in rsync protocol data stream (code 12).

Code 12 identifies a protocol data-stream failure, but it does not identify the root cause. Use the code to choose a layer, then confirm the cause with a targeted test.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Exit code Documented meaning What it narrows down
10 Socket I/O error Failure while reading from or writing to the network socket
12 Error in the rsync protocol data stream The two rsync processes stopped exchanging valid protocol data
23 Partial transfer due to error Some files or attributes were not transferred; inspect the preceding diagnostics
30 Timeout in data send or receive The connection stalled while transferring data
35 Timeout waiting for a daemon connection The client could not complete the initial connection to an rsync daemon

A code is a branch point, not a complete diagnosis. Record whether the failure occurs before any file list appears, during negotiation, or after data has transferred; that timing is often more useful than the wording alone.

Make the real diagnostic visible

When a remote rsync fails, its explanatory message can be hidden in the data stream that the local process is trying to decode. The Rsync Project recommends directing messages to standard error with --msgs2stderr -M--msgs2stderr where that option is supported by the rsync versions in use.

Use the option on a controlled reproduction, preserve both standard output and standard error, and compare the output from each side. If the installed version does not support the option, continue with the independent shell and daemon tests below rather than guessing from a one-line “connection closed” message.

Fix SSH and remote-shell transfers

1. Prove that the remote shell is clean

Run the remote-shell test with the same host and account used by rsync:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
ssh remotehost /bin/true > out.dat

If the shell is functioning correctly, out.dat should be zero length. Check its size with your normal file tool. Any text in the file is significant: a login startup file is writing to standard output during a non-interactive session. Typical sources include .profile, .cshrc, or another shell initialization script.

Rsync expects the remote shell to carry protocol bytes, not banners, status messages, command-not-found text, or diagnostic echo statements. Even a single unexpected line can corrupt negotiation and end as code 12 or a broken pipe.

2. Remove startup output without hiding real errors

Inspect the startup files for the account that rsync uses. Keep interactive-only commands behind the shell’s non-interactive check, and send intentional human-facing messages to the terminal only when an interactive shell is present. Do not simply discard all startup errors: a missing command or permission problem must remain visible while you test the account.

After editing the startup file, repeat the exact ssh remotehost /bin/true > out.dat test. Continue only when the file is empty. Testing with an interactive SSH session is not enough, because the contamination generally occurs only when rsync opens a non-interactive remote command.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

3. Verify that the remote rsync can start

Use the same account and host to check that rsync is installed and discoverable through the non-interactive PATH. For example, run a separate remote command that reports the executable location and version, then run the same check under the account’s actual service or restricted-shell configuration. The important conditions are:

  • The rsync executable exists on the remote host.
  • Its directory is included in the non-interactive account’s PATH, or the command uses the correct absolute path.
  • The account is allowed to execute it; a forced command, restricted shell, or policy can terminate it immediately.
  • The account can read the source or write the destination path named in the rsync command.

A remote process that exits immediately can look exactly like a dropped connection. A “command not found,” denied execution, inaccessible path, or policy rejection may be printed remotely and then reduced locally to code 12.

4. Check the path and permissions independently

Before repeating a large transfer, log in with the same account and test the relevant path using ordinary shell commands. Confirm that the source is readable, the destination directory exists, and the account can create or update the files and metadata that your rsync options request. Also check any mounted storage or network filesystem involved in the path.

This isolates filesystem failures from transport failures. If the account cannot access the path in a normal shell, changing SSH options will not repair the transfer.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Diagnose direct rsync-daemon connections

For host::module and rsync://host/module, there is no remote login shell whose startup output can be cleaned. The client connects to an rsync daemon, which applies module rules and parses the requested options.

Inspect the daemon log

Look on the daemon host for the connection time and the client address. The log can reveal a refused option, a read-only module, an access-control decision, an authentication failure, or another option-parsing error that the client cannot display clearly.

Older daemon versions could hide option errors from clients. If the log shows that behavior and the daemon is obsolete, upgrading it is a practical remediation; verify compatibility with the clients and module configuration before making the change.

Check module policy before changing the client command

Confirm that the module exists, is enabled for the requested host or account, and permits the requested operation. A module configured read-only will reject writes. Access rules can refuse a client before any file data moves. A daemon-side refusal often appears to the client as an unexpectedly closed connection when the useful explanation is recorded only in the daemon log.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Trace a daemon failure in the foreground

If the daemon appears to exit or crash, isolate it outside its normal service wrapper. The Rsync Project recommends running the daemon in the foreground with tracing so that the failure and its last diagnostic messages remain visible. Use the foreground and tracing method appropriate to the daemon version and service manager, and perform the test in a controlled maintenance window. Preserve the trace and the system log together; either one alone may omit the event that terminated the process.

Handle idle links and timeout failures

A connection can be healthy during active transfer and still be closed while it is idle. Long pauses can occur while rsync scans a large tree, waits on slow storage, or transfers a workload with little traffic. The Rsync Project notes that newer versions can send keep-alive messages during lulls, but the network and both endpoints still need a timeout appropriate to the workload.

Set rsync’s --timeout to a value that accommodates the longest expected quiet interval without leaving dead connections open indefinitely. Apply it to the actual transfer command and make sure the chosen value is reasonable for the network path, storage latency, and size of the file list. A value that is too short converts normal pauses into failures; a value that is too long delays detection of a genuinely lost peer.

Use the exit code to distinguish the stage:

  • 30 means the timeout occurred while sending or receiving transfer data.
  • 35 means the client timed out while waiting for a connection to an rsync daemon.

If the transfer fails only after a repeatable idle interval, compare that interval with firewall, proxy, VPN, load-balancer, and operating-system connection policies. If it fails while data is continuously moving, investigate socket errors, storage stalls, or a process termination instead of treating it as an idle-timeout problem.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Investigate a remote process that was killed or crashed

When shell output is clean, the remote executable starts, and the daemon path is correct, a remote-side termination becomes more likely. Inspect the server at the failure time for:

  • System and service-manager logs showing an rsync exit, signal, or restart.
  • Memory pressure or an out-of-memory action.
  • Process, file-descriptor, or other resource limits.
  • Filesystem-full conditions, storage errors, or failures on a mounted volume.
  • Daemon logs and, where available, a foreground trace.

Correlate timestamps from the client, SSH or daemon logs, and the operating-system log. A remote process that is killed after partial data transfer can produce both a connection-closed message and code 23; the earlier server event is the cause, while code 23 describes the incomplete result.

Do not assume that a successful SSH login proves the server is healthy enough for rsync. An interactive login can work while a service limit, memory event, storage fault, or daemon restart terminates the non-interactive transfer process.

Use failure timing as a decision tree

Observed timing Most useful next test What the result means
Failure before any file list or transfer begins Identify the transport, run the clean-shell test for SSH, or inspect the daemon log Focus on process startup, authentication, access control, option parsing, and protocol contamination
Failure during negotiation with code 12 Capture both sides’ diagnostics and verify that the remote process is the expected rsync version and executable Look for unexpected shell output, incompatible or refused options, and an immediate remote exit
Failure after some files have moved Check the exit code, timeout behavior, server resource logs, storage, and daemon trace Separate a data-transfer timeout, partial transfer, socket failure, or remote termination
Failure after a predictable quiet period Set a suitable --timeout and inspect intervening network-device idle policies Test an idle connection timeout rather than changing shell startup files

Common symptoms and the corrective action

“SSH works, but rsync fails immediately”

Test the non-interactive shell, not just an interactive login. A banner or command in .profile or .cshrc can leave an ordinary SSH session looking successful while corrupting rsync’s protocol. Then verify the remote PATH, executable, account restrictions, and transfer path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“The client reports code 12 with no useful remote message”

Enable --msgs2stderr -M--msgs2stderr where supported and preserve standard error. For an SSH transport, run the /bin/true zero-output test and verify remote startup. For a daemon transport, go directly to the daemon log; the client may not receive the option or policy error.

“It works for small jobs but fails on a long backup”

Record when the connection becomes quiet and whether the exit code is 30. If the failure aligns with an idle interval, choose a suitable --timeout and examine network-device idle limits. If the link is active when it fails, inspect storage, memory, process limits, and server logs instead.

“The transfer reaches some files, then the connection closes”

Use the final code and server timestamp. Code 23 confirms an incomplete transfer but not its cause. Code 30 points to a data-transfer timeout; code 10 points to socket I/O. A remote crash, resource kill, or storage error can also terminate an active transfer, so check the server rather than repeatedly rerunning the same command.

Validate the repair safely

  1. Keep the corrected command, transport type, rsync versions, exit code, and relevant logs together.
  2. Repeat the smallest transfer that reproduces the failure, using the same account, host, and path.
  3. For SSH, confirm that ssh remotehost /bin/true > out.dat still produces a zero-length file.
  4. For a daemon, confirm the module policy and check the daemon log for the test connection.
  5. Run the full transfer only after the small test completes without protocol or timeout errors.
  6. Record whether the failure was before negotiation, during negotiation, or after partial transfer so a later incident can follow the same branch quickly.

Rerunning without identifying the layer can obscure the evidence: a transient network event may disappear, while a contaminated shell, denied module, or killed remote process will continue to fail in a less obvious way.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Key points to remember

  • “Connection unexpectedly closed” means the rsync protocol connection disappeared; it is not a single fault.
  • SSH and direct daemon transports require different tests.
  • A non-empty out.dat from ssh host /bin/true > out.dat is evidence of unexpected shell output contaminating the protocol.
  • Code 12 is a protocol-stream error; code 10 is socket I/O; code 23 is a partial transfer; code 30 is a data-transfer timeout; and code 35 is a daemon-connection timeout.
  • When the remote process exits or crashes, server logs and a foreground, traced daemon are needed to find the cause.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.