Yesterday I wrote an entry about why servers running Ubuntu can stall on boot for two minutes ; the short version is that in 26.04, a network interface that either has no carrier or that has nothing else on it will cause systemd-networkd-wait-online to wait for two minutes in the hopes that this changes and the interface becomes healthy. My core diagnosis of the trigger for the problem was correct, but I had the wrong fix because in my testing, I made a classic mistake that's only really possible with virtual networking for virtual machines. There's an often invisible difference between an isolated virtual network interface and one that has no carrier , and I tested with an isolated interface, which stalls under some circumstances and fixed by some things, but not a virtual machine network interface with no carrier . The latter requires a more thorough fix.
I will put the answer at the front: you need to set every disconnected interface in your Netplan configuration to '
optional: true
'. Setting '
ignore-carrier: true
' isn't necessarily sufficient unless the interface has carrier. If you're mangling your 26.04 Netplan configuration anyway, I suggest you also set '
accept-ra: false
' on every inactive interface (and maybe your active one too, unless you use IPv6 RAs). However, you should not set '
optional: true
' on your main interface.
There are an assortment of things that will cause systemd-networkd-wait-online to think that it should wait until a particular interface is configured. A probably incomplete list of them is having a static IP address specified for an interface, having DHCPv4 or DHCPv6 enabled on the interface, and having
IPv6AcceptRA=yes
(to my surprise, although this is sort of covered in the documentation). Under normal circumstances, systemd-networkd will not do any of these things (or attempt them, for DHCP) if the interface has no carrier, which will cause the interface to not be configured. So it sounds like what you want is
ConfigureWithoutCarrier=yes
, so systemd-networkd configures the interface even without carrier and systemd-networkd-wait-online is happy. Unfortunately this has an important limitation spelled out in its documentation:
With this enabled, to make the interface enter the "configured" state, which is required to make systemd-networkd-wait-online work properly for the interface, all dynamic address configuration mechanisms like DHCP= and IPv6AcceptRA= (which is enabled by default in most cases) need to be disabled. [...]
(Although it's not really clear from the documentation, as far as I can see
IPv6AcceptRA=yes
is probably the default in many environments, as this manual page excerpt says.)
To disable this behavior when you have
ConfigureWithoutCarrier=yes
, in theory I believe you also need to set
RequiredForOnline=no
on the interface (or disable DHCP, IPv6 RA, and so on). Well, if you're working in a purely systemd-networkd world, which we're not on Ubuntu. Instead we're working in the world of Canonical Netplan .
Netplan doesn't simply run systemd-networkd-wait-online and let it decide what to do and what interfaces to consider. Instead, Netplan writes a drop in configuration file, /run/systemd/generator.late/systemd-networkd-wait-online.service.d/10-netplan.conf, and that configuration file tells systemd-networkd-wait-online specifically what interfaces to wait for and what (minimum) states they can be in; this minimum state is normally 'degraded' (as reported by networkctl . As far as I can see, Netplan will normally list and wait for every network interface that is mentioned in your Netplan configuration and that is not set as '
optional: yes
'. Also, systemd-networkd-wait-online specifically waits for all of these interfaces to not be in the 'configuring' setup state (again, as reported by networkctl , and as more or less documented in its manual page ).
If an interface has no carrier, it's permanently stuck in networkctl 's 'no-carrier' state and will never reach the 'degraded' state. If this interface is listed in your Netplan configuration, Netplan's systemd-networkd-wait-online configuration file will say it has to reach 'degraded', and so systemd-networkd-wait-online will time out. This happens regardless of what other Netplan properties you have set for that no-carrier interface; if it's mentioned at all and is not '
optional:
yes
', you will always have a two minute timeout on boot. This includes an interface with just a do-nothing property like '
renderer:
networkd
'.
If you specify '
ignore-carrier: true
' on an interface, Netplan will duly write
ConfigureWithoutCarrier=yes
to the applicable .network file. If an interface actually has carrier, this will make an interface with '
accept-ra: true
' (or no mention of it) finish configuration immediately regardless of whether or not something responds; the interface will be "degraded" but also "configured" and the systemd-networkd-wait-online configuration Netplan has created will consider it ready. This is unlike the standard behavior covered in the manual page quote above, because Netplan likes to surprise people.
(If DHCP is on for the interface, systemd-networkd won't complete configuration until and unless it gets a DHCP answer, and systemd-networkd-wait-online will have to time out.)
Setting '
ignore-carrier: true
' on an interface with a static IP in Netplan will allow that static IP to be configured even when there is no carrier, but it won't make that interface ready (by Netplan's standards) and so you'll still have that two minute timeout. The only way around the two minute timeout is to either not mention the interface at all in your Netplan configuration or to set it as '
optional: true
'. Both of these will cause Netplan to not list the interface as an interface that has to reach the "degraded" state and "configured" status in the systemd-networkd-wait-online configuration file it writes.
(I don't think Netplan ever writes
RequiredForOnline=no
into a systemd-networkd .network file it creates.)
If you set all interfaces in your Netplan setup to '
optional: true
', systemd-networkd-wait-online won't run at all under normal circumstances. This isn't obvious from the created configuration; Netplan will write a drop in configuration file for it that has no
ExecStart=
lines, which makes it seem like the standard .service file should take over and run systemd-networkd-wait-online in the standard way. However, the drop in file that Netplan writes does have a conditional dependency on /run/systemd/generator/network-online.target.wants/systemd-networkd-wait-online.service being a symbolic link, and Netplan doesn't set up that symbolic link, so the whole service is skipped. Given this, I think you almost certainly shouldn't set '
optional: true
' on all interfaces, which means not setting it on your main one (the one you're actually using).
(That systemd-networkd-wait-online doesn't run at all is obvious if you look at the logs, which will report that it's not running because its conditions aren't met.)