Ubuntu got a bug report (https://bugs.launchpad.net/ubuntu/+source/rsync/+bug/1774788) showing that rsync can fail to start during boot if a listen address is specified in the rsyncd.conf config file.
Since the systemd service file does not have a dependency on network-online.target, rsync tries to bind to the specific IP address from the "address" option and fails if it's not available.
A workaround is to add "After=network-online.target" to the systemd service file, but that is unnecessary for the common case where there is no specific address configuration. It's also a bit frowned upon in upstream systemd (see https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/).
For such cases, it is suggested to use the IP_FREEBIND socket option in linux. From the linux ip(7) manpage:
IP_FREEBIND (since Linux 2.4)
If enabled, this boolean option allows binding to an IP
address that is nonlocal or does not (yet) exist. This per‐
mits listening on a socket, without requiring the underlying
network interface or the specified dynamic IP address to be up
at the time that the application is trying to bind to it.
This option is the per-socket equivalent of the ip_nonlo‐
cal_bind /proc interface described below.
If this is done, please make it optional. I want my daemon to break when given an invalid config, e.g. a typo'd IP address. The fact that systemd folks are crazy and people don't want to have proper startup dependencies isn't a good reason to make the rest of us suffer unconditionally.
I agree with Carson. If rsync is told to do the impossible it should fail with an appropriate error and exit code.
Unfortunately I would also have to argue that the current behaviour is wrong because it does not exit with an error code and because I think the error message should also go to stderr instead of just syslog. A non-0 exit code would allow the launching script to simply keep trying until it works.
I think even the systemd people would prefer an explicit failure over an exit 0 with no output. A program that fails to do what it was told to do shouldn't be effectively the same as /bin/true.