Start with the systemd unit that actually owns the VPN connection, not with the log command you remember. A direct OpenVPN service, a wg-quick unit, and a NetworkManager profile place their useful messages in different units, and a query against the wrong one produces an empty result that looks like silence. Compare the three common owners, narrow the window, then read the stages in order.

Compare the three common owners

An OpenVPN client service is usually an instance unit named for the profile, such as [email protected]. Its messages include the configuration path, option parsing, the TLS handshake, and the route installation the client performs.

A wg-quick unit is quieter by design. The interface configuration happens at start, the handshake is handled by the kernel, and routine rekeys are not logged by default, so wg show is often more informative than the journal. That difference matters when you are comparing a protocol that logs negotiation with one that does not.

NetworkManager owns profiles it created, and its messages live under NetworkManager.service even when the underlying plugin is a VPN helper. Query both the manager and the helper unit when the profile is managed that way.

Narrow the query to one unit and window

Query the unit you identified, and bound the time to the attempt you are investigating. A day is usually enough, and a shorter window is better when the machine reconnects often.

journalctl -u [email protected] --since today
systemctl list-units --type=service | grep -i vpn
systemctl cat [email protected]

Verify the installed name before you trust the query. Distribution packaging renames units, and a profile that exists as a file may never have been enabled as a service. If the unit does not exist, the empty journal is telling you about the deployment rather than about the tunnel.

Read the first failed stage

Read the events in the order they occur: endpoint lookup, transport, identity, authentication, route installation, and the application's later failure. The first specific failure is the one worth investigating, because everything after it is a consequence.

A service that starts successfully does not establish that every required resource is reachable. A reconnect loop can produce several separate negotiations, so keep the profile name and the attempt time with the events, and read one attempt rather than a merged stream. A single attempt is a sequence with a cause, while a merged stream is a wall of repeated lines. Write the first error into the ticket before you read further.

Do not mix a failed service with a manual client

If you started a client by hand after the service failed, its output goes somewhere else and its behavior may differ. Capture the new result from the same owner and the same request after a supported correction, so the comparison shows what changed rather than mixing two different programs.

Do not alter original timestamps to align with another host. Record the timezone and any known clock difference separately, because a timeline you edited is no longer evidence.

Share an excerpt, not an export

Journal entries can contain usernames, endpoint addresses, private topology, and script environment information. Review the actual excerpt and redact what is sensitive rather than publishing a full unrestricted export. Quote the lines that establish the failure and summarize the rest. A short reviewed excerpt is easier to act on than a file nobody reads.

Send the narrow window, the unit name, and the first failed stage, and say what you already ruled out. The systemd journalctl manual documents the selectors and output options if you need a form the distribution's version supports.

Nsɛm a ɛfa ho