When a site's traffic is split across two stateful IPv4 NAT routers on separate uplinks, why do existing TCP sessions reset and inbound connections to a forwarded server hang?
answer
- each translator has its own table
- a session must return the same way
- new public address mid-flow
- reply leaves through the other exit
- stateless translation tolerates it
basics
~20 sEach NAT holds its own mapping state. A flow shifted to the other NAT emerges from a different public address and port, which the peer rejects; a forwarded server's replies leaving through the wrong NAT carry the wrong source.
solid answer
~50 sRFC 2663 and RFC 3022 both state that all requests and responses of a session must be routed via the same NAT router, because the translator holds the flow's state. If a failover or rebalancing moves an established flow from NAT A to NAT B, B has no mapping: it creates one with its own public address or drops the segment, and the server, seeing an unknown connection, resets it. For inbound traffic, A translates the destination to the forwarded server, but if the server's default route points at B, its SYN-ACK leaves through B, which drops it or sends it from B's address - and the client never completes the handshake. Fixes keep each flow on one translator - route each NAT's public addresses back only to it, return replies via the ingress NAT, or synchronise state between a pair sharing one address. Stateless NPTv6 (RFC 6296) tolerates asymmetry.
go deeper
Remember that a NAT keeps a record of every connection, so both directions of a connection have to pass through the same NAT.
Walk through what the second NAT does with a packet it has no mapping for, and why the remote server then resets the connection.
Diagnose from the symptom pattern - deaths at routing events, published services failing by source - and choose between pinning, return-path policy and state synchronisation.
Weigh where to keep state at a multihomed edge: redundancy, failover behaviour and translation design have to be planned together, and stateless designs remove the coupling.
## Why a translator cannot tolerate asymmetry An ordinary router keeps no memory of individual flows: it looks up each packet's destination and forwards it, so the two directions of a conversation may take different paths without harm. A NAT is different. It holds a **mapping** for every flow - which inside address and port became which public address and port - and can translate a packet only if that mapping is in its own table. RFC 2663 section 4.4 and RFC 3022 state the consequence: all requests and responses pertaining to a session must be routed via the same NAT router. RFC 2993 frames it through the end-to-end model: state held inside the network cannot be routed around unless it is replicated to the fail-over points. ## Failure 1: an outbound flow changes translator Two NATs, A (public `203.0.113.10`) and B (public `198.51.100.10`), each on its own uplink: 1. An inside host opens a TCP connection; its packets leave through A and are translated to `203.0.113.10:40001`. The server knows the connection by that address and port. 2. A link flap, a failover, a change in equal-cost load balancing or per-packet balancing moves the host's next packets to B. 3. B has no mapping for the flow. It either creates one with its own address - say `198.51.100.10:52310` - or, if it tracks TCP state, drops a mid-stream segment as belonging to no known session. 4. The server receives a segment for a connection it has never seen and answers with a reset, or the client simply times out. New connections keep working, which is why this hides: only flows that straddle the change die. ## Failure 2: a forwarded server replies through the other exit 1. A client connects to `203.0.113.10:443`; A's forwarding rule translates the destination to the inside server. 2. The server's default route points at B, so its SYN-ACK leaves through B. 3. B has no mapping matching that reply. Depending on the implementation it drops it, or translates the source to `198.51.100.10` as though it were a new outbound flow. 4. The client, which sent its SYN to `203.0.113.10`, receives nothing, or a SYN-ACK from an address it never contacted, and the connection hangs. ## Diagnosing it - Sessions die at a **routing event** - failover, metric change, rebalancing - while fresh connections succeed. - A published service works from some sources and hangs from others, depending on which exit the reply takes. - A capture outside one translator shows replies from the other translator's public address, or no replies at all. - One NAT's mapping table lacks flows whose other half appears in the other NAT's table. ## Fixes | Approach | How it restores symmetry | Cost | |---|---|---| | Pin each flow to one translator | Route each NAT's public addresses back only to it, and keep a flow's outbound path on the NAT where it started | A failover still breaks the flows on the failed box | | Return replies via the ingress translator | Policy routing so a forwarded server answers through the NAT its request arrived on | Extra routing policy per published service | | State synchronisation | The pair share one NAT configuration and exchange mapping state (RFC 2663 section 4.4), so the standby translates identically | Both must be able to own the same public addresses; replication lags under load | | Remove the state | Stateless, algorithmic translation such as NPTv6 in IPv6, or no translation at all | No drop-in equivalent for IPv4 address and port sharing | ## Preventing it at design time The cheapest fix is to decide, before the second uplink goes in, where every flow's state will live. Write down for each class of traffic - outbound browsing, published services, site-to-site links - which translator owns it, how its return path is guaranteed, and what happens to its sessions when that translator fails. A design that accepts "sessions on the failed exit restart" is honest and simple; one that promises seamless failover has to pay for shared addresses and state replication, and should be tested by pulling an uplink under load. ## Why stateless translation behaves differently RFC 6296 notes that identically configured NPTv6 translators compute the same mapping without exchanging dynamic state, so a network "can therefore asymmetrically route, load share, and fail-over among them without issue". The problem is per-flow **state**, not translation itself - which is also why two stateful firewalls on parallel paths fail in exactly the same way.
- Why does synchronising mapping state between two NATs only help if they can use the same public addresses?A replicated mapping records the external address and port the remote peer already knows. If the standby must translate to its own, different public address, the peer still sees a new source and rejects the flow, and return traffic for the old address is routed to the failed box. RFC 2663 describes NAT backup as boxes sharing the same NAT configuration and exchanging state.
- Why does the same pair of uplinks cause no trouble when the two boxes are plain routers?A router holds no per-flow state; each packet is forwarded by destination lookup alone, so either box can carry either direction of any conversation. Asymmetric paths only break devices that must see both directions or every packet of a flow - translators and stateful firewalls.
saying these in an interview costs you the question
- Asymmetric routing is harmless as long as both paths reach the destination.
- The second NAT will translate the flow exactly as the first one did.
- Per-packet load balancing across two NATs safely doubles throughput.
- State synchronisation fixes asymmetry even when each NAT uses its own public address.
- A forwarded server's replies can leave through any exit without consequence.