You start the client at boot, the unit reports active, and the tunnel is not there. The natural conclusion is that the service failed to start, and the natural fix is to start it again. Both are wrong often enough to be worth a rule: a running client that is retrying looks exactly like a broken one from the outside. The difference lives in what the process is doing, not in the unit state.

Myth: a started service means a working tunnel

An active unit proves the process was launched and has not exited. It does not prove the profile loaded, the certificate was accepted, or the far end answered. A packaged client can sit in a retry loop for minutes while systemd reports nothing but success. That gap between state and behaviour is the whole subject.

The opposite case is just as common. The process may have exited after failing to read a key, and the unit then reports a failed state that says nothing about why. Both states need the log to tell them apart.

Read the journal for the instance rather than the unit state. The reason line is in the log, not in the status label.

Myth: retry settings cover every failure

Name resolution and transport retries are separate controls with separate defaults. resolv-retry governs repeated lookups of a remote hostname, and the documented default keeps trying indefinitely. connect-retry sets the interval between attempts, while connect-retry-max can cap how many times each remote entry is tried. Check which stage the log names before changing any of them.

None of that applies to a malformed profile, an unreadable private key or a rejected account. Those need a correction, and a client that keeps retrying them is not making progress.

Retrying an unapproved certificate forever is not a reason to remove verification. It is a reason to read the error.

Myth: one launcher is enough, so add another

A connection already managed by NetworkManager or a packaged unit does not need a second launcher attached to it. Two processes competing for the same routes produce duplicate interfaces, confusing logs and a tunnel that flaps for reasons nobody can see. The second copy usually arrives as a workaround for the first one being slow.

Decide which component owns the tunnel before adding anything. Then remove the other launcher rather than disabling it and hoping.

The owner also determines where retries and credentials come from, which is why this decision comes before tuning anything. Ownership comes first for exactly that reason.

What actually needs ordering

Ordering can wait for a configured address, and that is all it guarantees. network-online.target delays activation until the manager considers the network up, and the definition of up depends on the manager. It says nothing about whether the VPN hostname resolves, whether the listener answers, or whether a captive portal has admitted the device.

Read the installed unit and any drop-ins before you add dependencies. A broad After= on every network service delays boot without establishing the connection you actually need.

Order the dependency you can test, and check everything else with a readiness probe. A probe that opens the tunnel beats a timer that guesses.

What happens after the tunnel first comes up

Boot is one event among many. The access link changes, a portal session expires, the peer restarts. Distinguish an internal reconnect from a process exit the service manager handles, because the two have different owners and leave different evidence.

Interactive authentication constrains unattended recovery. A background unit does not unlock a desktop keyring or answer an MFA prompt, so follow the approved credential arrangement for the service context.

Decide separately what applications may do while the tunnel is down. Retry restores a connection, while a blocking policy decides whether direct traffic is allowed in the gap.

Artihkkalat mat laktásit