systemd provides three target units related to network configuration:
network-pre.target is used to order services before any network interfaces
start to be configured. Its primary purpose is for usage with firewall services
that want to establish a firewall before any network interface is up.
network-pre.target is a passive unit: it cannot be started directly and it is
not pulled in by the network management service, but instead a service that
wants to run before it must pull it in. Network management services hence
After=network-pre.target, but not
Requires=network-pre.target. Services that want to be run before the network
is configured should use
Wants=network-pre.target. This way, unless there’s actually a service that
needs to be ordered before the network is up, this target is not pulled in,
avoiding an unnecessary synchronization point.
network.target indicates that the network management stack has been started.
Ordering after it has little meaning during start-up: whether any network
interfaces are already configured when it is reached is not defined.
Its primary purpose is for ordering things properly at shutdown: since the
shutdown ordering of units in systemd is the reverse of the startup ordering,
any unit that has
After=network.target can be sure that it is stopped
before the network is shut down when the system is going down. This allows
services to cleanly terminate connections before going down, instead of losing
ongoing connections leaving the other side in an undefined state.
network.target is a passive unit: you cannot start it directly and
it is not pulled in by any services that want to make use of the network.
Instead, it is pulled in by the network management services
themselves. Services using the network should hence simply place an
After=network.target stanza in their unit files, without
network-online.target is a target that actively waits until the network is
“up”, where the definition of “up” is defined by the network management
software. Usually it indicates a configured, routable IP address of some
kind. Its primary purpose is to actively delay activation of services until the
network has been set up.
It is an active target, meaning that it may be pulled in by the services
requiring the network to be up, but is not pulled in by the network management
service itself. By default all remote mounts defined in
/etc/fstab make use
of this service, in order to make sure the network is up before attempts to
connect to a network share are made. Note that normally, if no service requires
it and if no remote mount point is configured, this target is not pulled into
the boot, thus avoiding any delays during boot should the network not be
available. It is strongly recommended not to make use of this target too
liberally: for example network server software should generally not pull this
in (since server software generally is happy to accept local connections even
before any routable network interface is up). Its primary purpose is network
client software that cannot operate without network.
For more details about those targets, see the systemd.special(7) man page.
LSB defines a
$network dependency for legacy init scripts. Whenever systemd
$network dependency in LSB headers of init scripts it will
translate this to
After= dependencies on
network-online.target, staying relatively close to traditional LSB behaviour.
The meaning of
$network is defined only very
and people tend to have different ideas what it is supposed to mean. Here are a
couple of ideas people came up with so far:
All these are valid approaches to the question “When is the network up?”, but none of them would be useful to be good as generic default.
Modern networking tends to be highly dynamic: machines are moved between networks, network configuration changes, hardware is added and removed, virtual networks are set up, reconfigured, and shut down again. Network connectivity is not unconditionally and continuously available, and a machine is connected to different networks at different times. This is particularly true for mobile hardware such as handsets, tablets, and laptops, but also for embedded and servers. Software that is written under the assumption that network connectivity is available continuously and never changes is hence not up-to-date with reality. Well-written software should be able to handle dynamic configuration changes. It should react to changing network configuration and make the best of it. If it cannot reach a server it must retry. If network configuration connectivity is lost it must not fail catastrophically. Reacting to local network configuration changes in daemon code is not particularly hard. In fact many well-known network-facing services running on Linux have been doing this for decades. A service written like this is robust, can be started at any time, and will always do the best of the circumstances it is running in.
network-online.target is a mechanism that is required only to
deal with software that assumes continuous network is available (i.e. of the
simple not-well-written kind). Which facet of it it requires is undefined. An
IMAP server might just require a certain IP to be assigned so that it can
listen on it. OTOH a network file system client might need DNS up, and the
service to contact up, as well. What precisely is required is not obvious and
can be different things depending on local configuration.
A robust system boots up independently of external services. More specifically, if a network DHCP server does not react, this should not slow down boot on most setups, but only for those where network connectivity is strictly needed (for example, because the host actually boots from the network).
That depends on your setup and the services you plan to run after it (see above). If you need to delay you service after network connectivity has been established, include
This will delay boot until the network management software says the network is “up”. For details, see the next question.
The services that are ordered before
network-online.target define its
meaning. Usually means that all configured network devices are up and have an
IP address assigned, but details may vary. In particular, configuration may
affect which interfaces are taken into account.
network-online.target will time out after 90s. Enabling this might
considerably delay your boot even if the timeout is not reached.
The right “wait” service must be enabled:
NetworkManager is used to configure
Also=systemd-networkd-wait-online.service in its
[Install] section, so when
systemd-networkd.service is enabled,
will be enabled too, which means that
network-online.target will include
systemd-networkd-wait-online.service when and only when
systemd-networkd.service is enabled.
set up similarly. This means that the “wait” services do not need to be enabled
explicitly. They will be enabled automatically when the “main” service is
enabled, though they will not be used unless something else pulls in
To verify that the right service is enabled (usually only one should be):
$ systemctl is-enabled NetworkManager-wait-online.service systemd-networkd-wait-online.service disabled enabled
Please note that
network-online.target means that the network connectivity
has been reached, not that it is currently available. By the very nature and
design of the network, connectivity may briefly or permanently disappear, so
for reasonable user experience, services need to handle temporary lack of
If you are a developer, instead of wondering what to do about
please just fix your program to be friendly to dynamically changing network
configuration. That way you will make your users happy because things just
start to work, and you will get fewer bug reports. You also make the boot
faster by not delaying services until network connectivity has been
established. This is particularly important for folks with slow address
assignment replies from a DHCP server.
Here are a couple of possible approaches:
127.0.0.1only. These pseudo-addresses are unconditionally available. If you always bind to these addresses you will have code that doesn’t have to react to network changes, as all you listen on is catch-all and private addresses.
IP_FREEBINDsockopt functionality of the Linux kernel. This allows your code to bind to an address even if it is not actually (yet or ever) configured locally. This also makes your code robust towards network configuration changes. This is provided as
FreeBind=for systemd services, see systemd.socket(5).
An exception to the above recommendations is services which require network
connectivity, but do not delay system startup. An example may be a service
which downloads package updates into a cache (to be used at some point in the
future by the package management software). Such a service may even start
during boot, and pull in and be ordered after
network-online.target, but as
long as it is not ordered before any unit that is part of the default target,
it does not delay boot. It is usually easier to write such a service in a
“simplistic” way, where it doesn’t try to wait for the network connectivity to
be (re-)established, but is instead started when the network has connectivity,
and if the network goes away, it fails and relies on the system manager to
restart it if appropriate.
As described above, the meaning of this target is defined first by which
implementing services are enabled (
systemd-networkd-wait-online.service, …), and second by the configuration
specific to those services.
systemd-networkd-wait-online.service will wait until all
interfaces that are present and managed by
are fully configured or failed and at least one link is online; see
for details. Those conditions are affected by the presence of configuration
that matches various links, but also by settings like
It is also possible to plug in additional checks for network state. For
example, to delay
network-online.target until some a specific host is
reachable (the name can be resolved over DNS and the appropriate route has been
established), the following simple service could be used:
[Unit] DefaultDependencies=no After=nss-lookup.target Before=network-online.target Type=oneshot RemainAfterExit=yes [Service] ExecStart=sh -c 'while ! ping -c 1 example.com; do sleep 1; done' [Install] WantedBy=network-online.target