Infrastructure — Networking

Restoring a Failed OpenVPN Service — Diagnosing Stale Process Port Conflicts Under Systemd

A client's OpenVPN server refused to start after a routine maintenance window. Systemd kept retrying — and failing — each time masking the root cause behind a wall of log noise. Here is how we diagnosed it, what was really wrong, and what it taught us about service reliability under systemd.

The Challenge

The client reported that their OpenVPN access server was down. Users could not connect. A quick check showed the service in a restart loop:

systemd[1]: openvpn-server@server.service: Scheduled restart job, restart counter is at 10.
systemd[1]: Started openvpn-server@server.service ...
systemd[1]: Main process exited, code=exited, status=1/FAILURE

The restart counter was climbing past 20. The systemctl status output and journalctl offered no obvious clue — just exit code 1. We needed to find out why OpenVPN itself was refusing to start.

The Investigation

We checked disk space, file permissions, and the OpenVPN configuration — all looked normal. Then we tailed the OpenVPN daemon's own log file.

The output was telling. Buried beneath warnings about the deprecated --topology net30 setting, a single line stood out:

MANAGEMENT: Socket bind failed on local address [AF_INET]127.0.0.1:1197: Address already in use (errno=98)
Exiting due to fatal error

OpenVPN could not bind its management interface because something else was already listening on port 1197.

The Root Cause

A quick ss and lsof confirmed:

ss -ltnp | grep ':1197'
LISTEN 0 1 127.0.0.1:1197 0.0.0.0:*  users:(("openvpn",pid=3112668,fd=3))

A stale OpenVPN process — PID 3112668 — was still holding the management socket. This was a leftover from a previous run that had not been properly cleaned up, likely from a partial restart or a crash during the maintenance window.

Systemd was dutifully spawning a new instance, which would immediately fail because the port was taken, exit, and let systemd try again. The restart loop was working exactly as designed — but the design could not recover from a stale process that was not owned by the current service unit.

The Resolution

We killed the orphaned process:

kill 3112668

Confirmed the port was free:

ss -ltnp | grep ':1197'
# (no output)

Reset systemd's restart counter and started the service cleanly:

systemctl reset-failed openvpn-server@server.service
systemctl start openvpn-server@server.service

The service came up immediately. Clients reconnected. Total resolution time was under ten minutes.

The Outcome

Key Takeaways

  1. Systemd restart loops mask root causes. When the service exits immediately, systemd retries so fast that operators may not catch the real error message. Always check the application's own log, not just systemd's journal.
  2. Stale processes outlive systemd unit boundaries. A process spawned manually or left behind from a crash can hold ports, files, or locks that systemd's Restart= logic cannot clear. Always verify port availability with ss or lsof before assuming the service is at fault.
  3. The management interface is a single point of failure. OpenVPN's management directive binds to a fixed port. If that port is taken — by anything — the daemon refuses to start. Consider using a Unix socket (management /var/run/openvpn/management.sock unix) to avoid port conflicts entirely.
  4. Deprecation warnings deserve attention too. The --topology net30 warning was not the cause of this outage, but it flags a migration that should be scheduled before it becomes a problem in a future OpenVPN release.

Dealing with recurring service failures?

Validus helps organisations design, migrate, and maintain open-source infrastructure — from VPN platforms and identity management to full data-centre refreshes. If your team is dealing with recurring service failures or planning an infrastructure migration, we offer a no-obligation assessment.

Book Free Assessment