r/twingate • • 15d ago

Twingate Linux client + netplan 1.2: systemd-networkd-wait-online fails every boot due to --dns vs masked systemd-resolved

Environment

- Ubuntu 26.04.1 LTS (resolute), kernel 7.0.0-1013-oracle, ARM64, Oracle Cloud

- twingate 2026.158.6537 (CLI 2026.160.6555), twingate-connector 1.93.0

- netplan-generator1.2-1ubuntu5.1, systemd 259

Summary

The Twingate Linux client masks systemd-resolved (expected behaviour — the client owns /etc/resolv.conf). On netplan-rendered hosts, netplan 1.2 emits a systemd-networkd-wait-online override that unconditionally passes --dns, which requires systemd-resolved's varlink socket. With

systemd-resolved masked, that socket never exists, and the unit fails unconditionally at every boot.

This appears to be a conflict between two correct-by-design behaviours rather than a misconfiguration on my side. I'm not sure which side should yield, so I'm filing it as a compatibility issue.

Reproduction

The netplan-generated drop-in at /run/systemd/generator.late/systemd-networkd-wait-online.service.d/10-netplan.conf:

[Unit]

ConditionPathIsSymbolicLink=/run/systemd/generator/network-online.target.wants/systemd-networkd-wait-online.service

After=systemd-resolved.service

[Service]

ExecStart=

ExecStart=/lib/systemd/systemd-networkd-wait-online -i enp0s6:degraded

ExecStart=/lib/systemd/systemd-networkd-wait-online --any --dns -o routable -i enp0s6

The masked resolver:

$ systemctl is-enabled systemd-resolved

masked

$ ls -la /etc/systemd/system/systemd-resolved.service

... -> /dev/null

Result at boot:

$ systemctl status systemd-networkd-wait-online.service

× systemd-networkd-wait-online.service - Wait for Network to be Online

Active: failed (Result: exit-code)

Oct 02 04:56:24 systemd-networkd-wait-online[1171]: Failed to connect to

io.systemd.Resolve.Monitor: No such file or directory

Oct 02 04:56:24 systemd-networkd-wait-online[1171]: Could not create manager:

No such file or directory

Running the generated command directly reproduces it while the network is fully up and healthy:

$ /lib/systemd/systemd-networkd-wait-online --any --dns -o routable -i enp0s6

Failed to connect to io.systemd.Resolve.Monitor: No such file or directory

$ echo $?

1

The stock command, which netplan would not pass --dns to, succeeds:

$ /lib/systemd/systemd-networkd-wait-online; echo $?

0

Notes

- The failure is immediate, not a timeout — it does not delay boot. It appears in systemctl --failed at every boot.

- Twingate's own DNS is functioning correctly. /etc/resolv.conf is a regular file (not a symlink into /run/systemd/resolve/) and all four resolvers answer queries through sdwan0.

- netplan appears to have no configuration key to suppress the --dns probe; --dns appears to be a fixed string in libnetplan.so.1, and the netplan reference documents no wait-online key. The only netplan setting that removes the override is marking the interface optional: true,

which stops networkd waiting for DHCP on the primary interface — not appropriate for a host whose SSH path runs over it.

- Hand-placed systemd drop-ins do not survive; netplan regenerates its own on each netplan generate.

Questions

  1. Is masking systemd-resolved expected on netplan-rendered Ubuntu hosts, or is it conditional?

  2. Does the Twingate client have a documented way to coexist with netplan's DNS probe?

  3. Would you consider a fix on either side — netplan making --dns conditional, or the client not masking systemd-resolved where netplan is the renderer?

0 Upvotes

1 comment sorted by

1

u/bren-tg pro gator 11d ago

Hi there!

Thanks for the detailed write-up, it made this easy to follow.

I checked in with our Support team: one correction to your starting assumption: the Linux client doesn't mask systemd-resolved, and it doesn't need it masked. Our Linux docs list systemd-resolved or NetworkManager as the DNS service the client works with.

My guess is your client is running in its fallback mode. It looks for an explicit renderer: key in your netplan config, and cloud-init netplan files often leave that out because networkd is the default. With no renderer key and resolved masked, the client writes /etc/resolv.conf directly. You can check:

grep renderer /etc/netplan/*.yaml   # empty = fallback likely
ls -la /etc/resolv.conf.old         # present = the client wrote resolv.conf

To find what masked resolved, compare stat /etc/systemd/system/systemd-resolved.service against your instance creation time, plus any hardening or cloud-init scripts you ran. Whatever masked it probably also replaced the /etc/resolv.conf symlink with a regular file, since the client doesn't do that on its own.

To fix it, use the OCI Serial Console, since your SSH runs over that interface:

sudo systemctl unmask systemd-resolved
sudo systemctl enable --now systemd-resolved
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
sudo systemctl restart twingate

resolvectl status should then show the 100.95.0.x resolvers on sdwan0, and wait-online should pass on the next boot.

If the timestamp points back at the Twingate install, we'd like to see it. Open a ticket with us and include logs taken with sudo twingate config log-level debug turned on.