The service fails, the logs mention a spawn and a directory, and the first instinct is to check the VPN configuration. Nothing in that file has been read yet. systemd failed while preparing the process, before the executable ran, so no parser, no certificate and no remote host has been consulted. Reading the status code as a statement about systemd rather than about OpenVPN is what turns this into a short investigation.

Read the status code before the application

The numeric code after the service name names the stage that failed. A directory failure is reported as a CHDIR status, while an executable that could not be run is a different code entirely. Those two look similar in a summary line and have nothing in common in their causes.

That distinction matters because the fixes are in different files. A CHDIR failure is about a path and the service's view of it. An exec failure is about the binary, its interpreter or an unrelated mount. Changing the VPN remote, the cipher list or the certificate path cannot address either one.

Confirm the failure is at start rather than after a successful run. If the service worked yesterday and now fails at the same stage, something changed about the directory, its permissions or the unit itself, and that change is the evidence to look for.

Ask the unit where it wants to be

Read the effective unit rather than the file you believe is installed, because drop-ins can override the working directory without your ever editing the main unit. The show output answers the question directly:

systemctl cat [email protected]
systemctl show [email protected] -p WorkingDirectory -p RootDirectory -p User -p ProtectHome
journalctl -u [email protected] -b --no-pager | tail -30

For the upstream server template, the working directory is the server configuration directory and the instance name selects the profile inside it. An instance called branch therefore expects its own file in that same directory, and a profile placed elsewhere does not satisfy the working-directory requirement at all.

Compare what the unit asks for with what exists. A path that used to exist, a symlink that now points somewhere else, or an instance name that no longer matches a directory are all ordinary changes that produce this exact failure.

Check the path as the service sees it

Your shell and the service do not share a filesystem view. A configured root directory or root image changes what an absolute path means inside the unit, and a path that is obviously present on the host may be absent in that namespace. Read the unit's settings before trusting a manual test.

Permissions compound the problem. The service runs as a specific user, and that user must be able to traverse every parent directory to reach the target, not merely read the target itself. A directory readable by root and not traversable by the service user produces a failure that looks like a missing path.

namei -l /etc/openvpn/server
systemctl show [email protected] -p ProtectSystem -p ReadOnlyPaths

Hardening settings are part of this picture as well. A unit that hides home directories or makes part of the filesystem read-only is doing exactly what it was configured to do, and the working directory needs to live somewhere the sandbox still exposes.

Fix the owner, then expect a different error

Correct the layout or the unit through whoever owns that configuration. Moving a profile into the expected directory is a legitimate fix when the layout is wrong, but it does not explain a directory that cannot be entered, so do not treat it as the general answer.

Resist the shortcut of widening permissions on the configuration tree or removing the sandbox. Both make the symptom disappear while removing the protections that were put there deliberately, and the next failure will be harder to interpret.

Restart the instance and read the next event rather than assuming success. The likely next error is that OpenVPN cannot open its configuration file, which is progress: the working directory was entered and the parser is now running. Follow the unit's actual file mapping from there instead of returning to network troubleshooting.

The systemd execution reference defines how the working directory is interpreted alongside root directories and sandboxing. The pattern to remember is simple: each status code names a different stage, and only the application's own errors describe the application.

ХӀокхунах тера йаззамаш