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.