I use a backup system called backuppc and have for many years, and it has never failed me. I like it because it is very flexible, and it can deduplicate backups across all hosts. I also use borg backup which is also a very nice solution but only deduplicates per backup repository which is usually per host.
Anyway, the problem was that I use a script to run rsync, and that script was called over ssh to push the backup from the client to the server. The script is basically a one-liner that repeats the arguments sent from the server:
exec /usr/bin/nice -n 19 /usr/bin/rsync "$@"
While deploying the backup system to a bunch of new hosts I noticed that some didn't have rsync installed. That was quickly fixed by updating my configuration management, but I thought it would be nice to add a check if rsync was available to the script, and to exit with an error if not. What I did not consider, I didn't suppress the output of the check. The example below has this problem fixed so that nobody ends up copy and pasting the mistake.
if ! command -v rsync >/dev/null 2>&1; then echo "Please install rsync" exit 1 fi
I did not dig deeper, but in this particular setup it seems like pushing the rsync changes broke because of the unexpected script output and caused rsync to hang forever. In a strace rsync this appeared as a repeatedly timing out select() call.
In the end everything was fine for me. There were no backups in ten days but all my work was either pushed into remote repositories or mirrored on my laptop. I ended up configuring borg as well before fixing the problem and can now use it as a fallback backup solution if backuppc ever stops working again.