The command works when you are logged in, so you put it in a startup script and go home. The next morning the machine is online and the tunnel is not. The myth is that a working invocation is a working service. In practice the difference is usually one of two things: the profile belongs to your user session rather than the system, or the secret is unlocked by something that only exists after you log in. Both work perfectly in a manual test and fail at exactly the moment nobody is watching.

Why login makes it work

A graphical login starts a session bus and a secret service agent, which is where many desktop-oriented clients keep the profile's password or private-key passphrase. An activation that runs as your user after login can ask that agent for the secret and succeed. The same activation executed by a boot-time unit has no session, no bus and no agent, so the lookup fails or blocks on a prompt nobody sees.

Run the same profile before and after logging in and you get two different outcomes from one configuration. That is the signature of a credential dependency, not of a broken tunnel, and it explains why a manual test in a terminal proves less than it seems to. The tunnel is fine; the thing that unlocks its secret is missing.

Decide which owner starts the tunnel

There are two supported patterns, and mixing them is the other way this fails. NetworkManager can activate a system-scoped connection, which is appropriate when the machine already centralises its networking there. Alternatively, a dedicated systemd unit runs the VPN directly and owns the interface itself.

systemctl list-unit-files 'openvpn*'
systemctl list-unit-files 'wg-quick*'
nmcli connection show --active
systemctl enable --now wg-quick@wg0

Do not run both owners against one configuration. If NetworkManager manages the interface and a unit also brings it up, they will fight over routes and DNS, and the resulting state depends on which finished last.

Put the secret where a service can read it

A background service cannot answer a prompt. Certificate passphrases, account passwords and referenced auth files all need a storage arrangement the unit can reach without a human, owned by the account that runs the service and unreadable by everyone else.

The tempting shortcut is to make the file world-readable until the permission error disappears. That trades a startup failure for a long-lived credential exposure, and it is the kind of change nobody revisits. Use the mechanism the deployment already trusts: a restricted credentials file, an unencrypted key that is protected by file permissions, or a system-scoped connection with its own secret storage.

Test the event that actually happens

Starting the service manually after login tests almost nothing. Reboot, or disable the graphical login for one cycle, and watch the unit come up on its own. That is the only test that exercises credential availability, network readiness and unit ordering together. It is also the test that reproduces the failure the user reported, which a manual start never does.

systemctl is-enabled wg-quick@wg0
journalctl -u wg-quick@wg0 -b --no-pager
systemctl status systemd-networkd-wait-online --no-pager

Ordering matters as much as credentials. A unit that starts before the underlying uplink is configured will give up, and some distributions differ in whether they wait for connectivity. If the unit reports failure at boot but succeeds when started by hand thirty seconds later, you have found an ordering problem rather than a secret problem.

Verify routes and DNS, not just the interface

An interface that exists is not a working tunnel. After an unattended start, check the routes, the resolver state and one destination by address before checking a name. Then check the application the tunnel exists for.

ip -4 route show
resolvectl status
ping -c 3 10.61.0.1
curl -sS --max-time 5 https://internal.example/ -o /dev/null -w '%{http_code}\n'

If the address works and the name does not, the remaining problem is DNS policy and not the tunnel. Record which owner starts the service and where the secret lives, because the next person to reboot this machine will need both facts.

Inyandiko zihuye