Here's something that bit me recently.
You write a service unit with After=network.target, thinking your database will wait for the network. It doesn't. network.target only means the network stack is up — not that an interface has an IP, not that DNS works, not that you can reach anything.
The trap
[Unit]
Description=My Database
After=network.target
Looks right. But network.target is passive — it's pulled in by things that provide network, not things that require a working connection. Your service starts, tries to bind to 0.0.0.0:5432, and if the interface hasn't come up yet (DHCP, WiFi, VPN, whatever), it binds to nothing useful or fails silently.
The fix
[Unit]
Description=My Database
After=network-online.target
Wants=network-online.target
And enable the waiter:
systemctl enable systemd-networkd-wait-online.service
network-online.target is the one that actually waits for systemd-networkd (or NetworkManager, or whatever) to report "yeah, we're online." Wants= pulls it in so the target is active. After= orders after it.
The gotcha
If you're not using systemd-networkd — say you're on NetworkManager — you need:
systemctl enable NetworkManager-wait-online.service
Same idea. Different service name.
How to verify
systemctl show -p ActiveState network-online.target
# Should say 'active'
systemd-analyze plot > boot.svg
# Open it, find your service, see what it actually waited for
The plot doesn't lie. Your service bar should start after the network-online target bar ends.
Not a novel discovery. Just one of those things that's documented but easy to miss when you're in a hurry.
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.