Summary
VyOS ships two independent paths from journald into rsyslog, so every log entry is stored twice locally and transmitted twice to any remote syslog target.
data/templates/rsyslog/rsyslog.conf.j2 loads both input modules:
module(load="imuxsock") module(load="imjournal" StateFile="/var/spool/rsyslog/imjournal.state" ...)
/etc/systemd/journald.conf ships with ForwardToSyslog=yes. This is a modification to the Debian conffile, which ships with every option commented out:
$ sudo dpkg --verify systemd | grep journald ??5?????? c /etc/systemd/journald.conf
The file's mtime is the image build date (2026-03-19 07:03:08, zero nanoseconds), not a date from the running system, so it arrived with the image rather than being edited locally.
journald therefore forwards each entry to /run/systemd/journal/syslog, where imuxsock collects it, while imjournal independently reads the same entry from the journal.
Reproduce
No configuration change required. Default install, local logging only:
$ logger -t duptest "single message reproducer"
$ sudo grep duptest /var/log/messages
Aug 9 18:38:05 vyos duptest: single message reproducer
Aug 9 18:38:05 vyos duptest[24467]: single message reproducer
Actual: two entries per event. Expected: one entry per event.
logger emits exactly one message, so this is not an application logging twice. The two lines differ only in the tag — one carries the PID, one does not — which identifies the mechanism: imjournal renders SYSLOG_PID from the journal's structured fields, while the socket-forwarded copy arrives without it. A single message written by two rsyslog actions would be byte-identical.
Not caused by having both local and remote targets
Both copies appear in the same destination (/var/log/messages), and the duplication is present with only local logging configured — the reproducer above requires no system syslog remote. On a system that does have a remote target, the remote receives two copies as well.
Impact
Doubles local log storage.
Doubles bytes sent to every remote syslog target, and doubles storage consumed on the collector. Where the collector has a size or retention cap, effective retention is halved.
Any downstream analysis that counts events — rate limiting, alerting on repetition, SIEM correlation — sees each event twice.
Suggested fix
Either is sufficient.
(a) Ship ForwardToSyslog=no, or a drop-in under /etc/systemd/journald.conf.d/, leaving imjournal as the single source. This is the smaller change and does not affect any other consumer.
(b) Do not load imuxsock. Under systemd, /dev/log is journald's socket, so programs logging via syslog(3) reach rsyslog through imjournal regardless. Here imuxsock binds /run/systemd/journal/syslog and receives only what journald forwards — i.e. the duplicate.
Caveat on (b): /etc/rsyslog.d/49-haproxy.conf uses $AddUnixListenSocket for its own socket, which is an imuxsock directive. If that file is shipped by VyOS, removing the module would need that handled. This has not been verified, which is why (a) is offered first.
Workaround
sudo mkdir -p /etc/systemd/journald.conf.d
printf '[Journal]\nForwardToSyslog=no\n' | \
sudo tee /etc/systemd/journald.conf.d/10-no-syslog-forward.conf
sudo systemctl restart systemd-journald rsyslog
This does not survive add system image: a new image starts from a fresh squashfs, so the duplication returns silently after an upgrade.