Stop network-online.target Waiting on the Wrong Link
When a boot hangs for two minutes on a link nobody needs, the culprit is usually systemd-networkd-wait-online waiting on the wrong interface. This guide shows you what it is waiting for, how to test a narrower condition, and how to make a persistent per-interface override. The examples target systemd 255, installed here as package version 255.4-1ubuntu8.17.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell, systemd-networkd managing the relevant interface, and permission to read system state. The inspection commands are ordinary and read-only. Editing a unit drop-in needs sudo and changes boot ordering, so keep the recovery step nearby.
1. See the links and the unit state
Start by listing links known to networkd and checking the wait service. None of these commands change networking:
$ networkctl list
$ systemctl status systemd-networkd-wait-online.service
$ systemctl cat systemd-networkd-wait-online.service
The installed unit is a oneshot service. It runs /usr/lib/systemd/systemd-networkd-wait-online, stays active after success, and is ordered before network-online.target. The stock unit ships with no command-line options, but a host can also carry a drop-in, so read the complete output from systemctl cat rather than assuming the file under /usr/lib/systemd/system is the whole story.
Checkpoint
Note the interface name that must provide connectivity, such as enp1s0 or eth0. Replace that placeholder in every later command. Interface names are host-specific; do not copy one from a different machine.
2. Understand what the default waits for
Run the helper directly for a read-only test. It may wait up to 120 seconds, its documented default timeout:
$ /usr/lib/systemd/systemd-networkd-wait-online --timeout=15
$ printf 'exit status: %s\n' "$?"
exit status: 0
Success means every managed link known to the helper is configured or has failed, and at least one link is online. In the default definition, online means an operational state of degraded or higher. It does not mean every link has a default route, that DNS works, or that an application can reach its remote service, that is a different check entirely.
The fifteen-second limit above is only for this manual test; it does not change the service's real 120-second default. A non-zero status means the condition was not met before the test ended. Look at the links again:
$ networkctl status --all --no-pager
Look for a link stuck configuring, a missing carrier, or an interface networkd is managing that you do not actually need for the boot transaction.
3. Test the interface that actually matters
When one link is the real dependency, select it explicitly, which causes other interfaces to be ignored:
$ /usr/lib/systemd/systemd-networkd-wait-online --interface=enp1s0 --timeout=30
$ printf 'exit status: %s\n' "$?"
exit status: 0
The interface-only form still accepts the default minimum operational state, degraded, unless the matching .network file supplies RequiredForOnline=. You can make the threshold explicit yourself. For a link that must have a usable route, require routable:
$ /usr/lib/systemd/systemd-networkd-wait-online \
--interface=enp1s0:routable --timeout=30
Operational states are ordered by networkd, and the important distinction here is that degraded is weaker than routable. A link can be configured enough to satisfy the former while still missing what your service actually needs. Run networkctl status enp1s0 to see the current state before you raise the threshold.
Checkpoint
Do not reach for routable just to make a slow boot error look more dramatic. It is a stricter requirement and can make a machine wait or fail when local-link connectivity was already sufficient.
4. Add an address-family requirement when needed
Operational state alone is not always enough. Add --ipv4 when the dependent service specifically needs an IPv4 address:
$ /usr/lib/systemd/systemd-networkd-wait-online \
--interface=enp1s0:routable --ipv4 --timeout=30
With an interface selected, the helper waits for that interface. Without one, the address-family condition applies to every interface under consideration instead. The installed manpage also supports --ipv6. If neither family option is supplied, networkd's RequiredFamilyForOnline= setting in the matching .network file is used when present.
For redundant links, --any flips the meaning from all selected interfaces to at least one:
$ /usr/lib/systemd/systemd-networkd-wait-online \
--interface=enp1s0 --interface=enp2s0 --any --ipv4 --timeout=30
Use this only when either link really is an acceptable path. Pairing --any with two interface names is not a way to hide a failed primary link if your application actually depends on that specific one.
5. Persist a narrow policy with a drop-in
Only do this once the direct test in the previous steps has already succeeded. This changes the service used during boot and needs elevated privileges. Create an override:
$ sudo systemctl edit systemd-networkd-wait-online.service
Enter the following, swapping in enp1s0 and choosing the family and threshold your dependency needs:
[Service]
ExecStart=
ExecStart=/usr/lib/systemd/systemd-networkd-wait-online --interface=enp1s0:routable --ipv4 --timeout=30
The empty ExecStart= clears the vendor command before the replacement gets added; without that line, systemd would reject defining a second command for this service. The drop-in normally lands under /etc/systemd/system/systemd-networkd-wait-online.service.d/. Confirm what systemd now sees:
$ systemctl cat systemd-networkd-wait-online.service
$ systemctl show systemd-networkd-wait-online.service -p ExecStart
Do not edit the vendor file under /usr/lib/systemd/system, package upgrades can replace it outright. The drop-in is the local administrator's layer, and it is far easier to audit and remove.
6. Recover from a bad override or a timeout
If the new policy causes an unwanted boot delay, inspect the exact interface state first:
$ networkctl status enp1s0 --no-pager
$ journalctl -u systemd-networkd.service -b --no-pager
Check spelling, carrier, DHCP or IPv6 availability, and whether the requested operational state is even realistic. Do not just keep raising the timeout as a substitute for fixing a missing link or a wrong address-family requirement.
To remove the local override entirely and return to the packaged unit, use this reversible action:
$ sudo systemctl revert systemd-networkd-wait-online.service
$ sudo systemctl daemon-reload
$ systemctl cat systemd-networkd-wait-online.service
systemctl revert removes administrator drop-ins for this unit, so review its output first and skip it if you have other deliberate local overrides that must stay. If the unit is currently running, a later boot or an explicit service start will use the restored definition. The command does not fix a physical link, DHCP server, routing policy or networkd configuration, only the wait-online policy.
Done means
- Link identified: you know which link the dependent service actually needs.
- Test run: you tested that link with a bounded timeout and checked the exit status.
- Threshold deliberate: you chose
degradedorroutableon purpose, not by guessing. - Family scoped: you added
--ipv4,--ipv6or--anyonly where the dependency actually requires it. - Recovery known: if you changed the service,
systemctl catshows the drop-in and you know thesystemctl revertrecovery command.