The laptop moves from office Wi-Fi to a phone hotspot, the tunnel stays up for a few more seconds, and then traffic stops while the interface still claims to be connected. On the server, the status list keeps showing the old public address. This is the situation float exists for, and it is also the situation where people expect it to do far more than it does. Getting the boundary right turns a confusing stall into either a one-line configuration change or a completely different investigation.

What float relaxes, and what it never relaxes

Normally a session keeps talking to the outer address and port it started with, and packets arriving from anywhere else are ignored. The float option removes that strict binding once the peer has already proven itself, so a changed source mapping can continue the same session instead of being dropped. Nothing about the cryptographic checks changes: keys, certificates and any HMAC protection remain exactly as configured.

This is a per-packet decision, not a policy about who may connect. An unknown machine that sends a packet from a new address has proven nothing, and its packet is discarded like any other unauthenticated traffic. Only traffic that passes the session's own authentication can move the recorded peer address, which is why float is safe to leave on in environments where clients roam.

It also says nothing about the inner tunnel. A moved outer address does not reassign a tunnel address, change the pool, or grant the peer access to something new. Inside the tunnel, the same identity and the same pushed routes apply before and after the move. A roam does not renegotiate the data channel either, so the negotiated cipher and keys carry on.

The packet that moves a session has to authenticate

Start a session the ordinary way against the configured remote, and float handles what happens when the mapping changes. A mobile carrier that renumbers mid-flow, a NAT gateway that rewrites its port mapping, or a laptop that switches uplink all produce the same shape: authenticated packets from a new tuple, arriving on a session that still believes in the old one.

Whenever you are asked whether float is working, the useful evidence is a completed handshake followed by a source change that was accepted, not a log line about the address alone. Correlate the old and new outer addresses against the session that stayed alive, then confirm that traffic actually continued through the tunnel.

If the session dies instead of moving, the packet that arrived from the new address probably failed authentication or never arrived at all. Both cases look identical from the client. On the server, a capture on the public interface tells you which one you have before you touch any configuration.

Discovery is a separate mechanism entirely

float does not resolve names on a timer and does not track a dynamic DNS record. If the server's hostname starts resolving to a new address, an idle client has no reason to notice and no packet from the new endpoint to authenticate. That problem belongs to reconnection logic, to the client's own retry behaviour, and to DNS, not to float.

Adding the option once more cannot compensate for having no route to the new address. Neither can it help when the peer is silent, because a silent peer never sends the authenticated packet that would move anything.

The underlay firewall gets a vote too. A rule that only permits the old outer endpoint blocks the changed address before OpenVPN ever sees it, and no amount of client-side configuration fixes that. Review the permitted-address lifecycle as its own task; widening the rule to any source trades a small problem for a large one.

When NetworkManager owns the profile

A command-line profile and an imported connection are separate configurations, and editing one does not touch the other. Before assuming the option is unsupported, establish which plugin type the saved profile actually uses and where its values live. The profile UUID is the identifier that matters when you inspect or modify anything.

Inspect the saved connection rather than the original import file. A line that survives in a .ovpn file proves nothing if the active manager never applied it, and an editor without a checkbox for a given option proves nothing about the protocol's capabilities either.

Do not patch a packaged plugin to add the behaviour, especially not with a diff written for a historical version of an unrelated component. If the installed integration genuinely cannot express the setting, the correct move is a supported profile or a different client path approved by whoever owns the deployment.

Prove the transition instead of assuming it

Run the test the way the failure happens. Connect, verify traffic through the tunnel, force the outer address to change, and then check three things: the session still exists, the recorded peer address has moved, and a real request still reaches its destination. Anything less than all three is a partial answer.

Keep recovery access available while you test, because roaming experiments have a habit of stranding the machine you are working from. A serial console or an out-of-band route turns a failed test into a five-minute recovery instead of a site visit.

Finally, describe only the case you exercised. A successful address change during a session is not evidence that DNS migrations, a different client implementation, or a rebuilt profile will behave the same. The link-options documentation states the option's scope precisely; your test log should state which part of that scope you actually covered.

Artihkkalat mat laktásit