IPv6 stops passing traffic the moment OpenVPN restarts, and IPv4 keeps working. The tunnel interface was recreated, and something else that was managing its IPv6 state either lost the address or lost the route that makes the prefix reachable. Three separate pieces of state are involved, and each has a different owner: the provider's delegated prefix and its lifetime, the addresses handed to VPN clients, and the upstream route that sends that client prefix back to the server. Identify the owner of each before you touch a daemon, because restarting the wrong one hides the problem for a day and returns it on the next reconnect.

Three pieces of IPv6 state, three owners

StateTypical ownerWhat breaks when it is wrong
Delegated prefix and lifetimeUpstream router or provider via DHCPv6-PDClients keep addresses that the upstream no longer routes
Client addresses inside the tunnelOpenVPN server config or a delegation daemonNo global address, or an address outside the routed prefix
Return route for the client prefixUpstream router, or the server's own routing tableOutbound works, replies never arrive

A globally scoped address inside the tunnel is not enough on its own. Upstream routers still have to send that prefix back toward the VPN server, and they will not do it because the server happens to hold an address from it.

This is also why copying a public /64 into a tunnel pool is risky. A prefix routed to the server is not the same as a prefix the upstream treats as on-link, and neighbour discovery will not fill the gap.

Read the server state before changing anything

Capture the state twice, once while IPv6 works and once after the restart, then compare. Read-only views are enough, and they cost nothing during a maintenance window:

ip -6 addr show
ip -6 route show table all
ip -6 rule show
sysctl net.ipv6.conf.all.forwarding

Look for three specific differences: a route that disappeared, an address that moved to a deprecated or invalid lifetime, and a prefix that changed after re-delegation while the VPN configuration still advertises the old one.

If the address vanished but the prefix is unchanged, the daemon that assigns it stopped managing the interface. If the prefix changed but the addresses did not, the client configuration is stale. The two failures look identical from a browser and have nothing in common.

Decide whether dhcpcd should manage the tunnel

dhcpcd can discover interfaces and delegate parts of a DHCPv6 prefix to downstream interfaces, and its configuration can name the delegation targets explicitly. Without an explicit target, its documented behaviour can involve other interfaces, which is how a tunnel ends up with an address nobody planned.

Two conditions should push you toward letting OpenVPN own the tunnel's static addressing: the server pushes fixed addresses in its configuration, and the tunnel name changes on reconnect. If both hold, exclude the tunnel from the delegation daemon deliberately, with a comment that says why.

If delegation to the tunnel is deliberate instead, implement the prefix-change handling. That means reacting when the delegated prefix or its lifetime changes, updating the server's advertised client prefix, and re-adding the route. Excluding the interface in that design removes the only component that knows about the new prefix.

Restarting dhcpcd may appear to fix things because it recreates state, but it also renews or withdraws configuration for interfaces you were not thinking about. That recovery does not make it a requirement after every VPN restart. It also resets the counters you were using as evidence. Prefer a targeted reload of the interface you actually changed.

Validate IPv6 separately from IPv4 NAT

Confirm forwarding is enabled and that the upstream route points at the actual client prefix, then make a fresh permitted IPv6 connection. Check the client's own IPv6 route table as well, because a client showing a public address does not prove its request used the tunnel.

IPv4 masquerading solves a different problem: the return path for private sources. It does nothing for a withdrawn IPv6 prefix, and adding it will not bring IPv6 back.

Close with the ownership record: which component delegates the prefix, which assigns client addresses, which holds the return route, and what happens to each on reconnect. Four lines in a runbook save the next person from restarting three daemons to find the one that mattered.

Sɛbɛn minnu bɛ tali kɛ