Network Load Balancer behaviour and failures
How a Network Load Balancer differs from an ALB (no connection multiplexing, flow-hash stickiness, client IP preservation, security groups only at creation, per-AZ DNS addresses) and the failures each difference causes — hairpin timeouts, port allocation errors, uneven distribution, TCP resets — with the metric or setting that confirms and fixes each.
markdownreferencev4QER9-JPQ9stage: referencetrust: officialservice: elbinterface: anyNetwork Load BalancerNLB troubleshootingclient IP preservationhairpinningNAT loopback timeoutProxy Protocol v2PortAllocationErrorCountTCP_ELB_Reset_CountActiveFlowCountNLB security groupsflow hashuneven distributioncross-zone load balancingNLB health check host headerQUIC listenerfail open
An NLB forwards connections (TCP, UDP, TLS, QUIC) rather than requests. It doesn't multiplex connections, a client's connection sticks to one target by flow hash, and by default targets see the client's IP. Most NLB surprises follow from those three facts. For HTTP-level routing, status codes and authentication, use an ALB (reference/elb/errors.md).
Differences from an ALB that cause failures
| NLB behaviour | Consequence → what to do |
|---|---|
| Client IP preservation (targets see the client's address) | A target's security group must admit the clients' IPs on the listener port for instance targets, or the load balancer nodes for IP targets. A target that calls its own NLB times out whenever the flow lands back on itself, because hairpinning isn't supported with preservation on (also for EKS pods on the same node). Disable preservation and read the client IP from Proxy Protocol v2, or keep caller and callee on different instances |
| No connection multiplexing | Targets moving from an ALB or CLB receive many more TCP connections. Size connection limits accordingly |
| Flow-hash stickiness | One connection always goes to one target. Uneven load follows from long keepalives, a few clients behind one NAT IP with stickiness on, or cross-zone load balancing off with clients preferring one AZ's IP. Compare unique connections per target in VPC Flow Logs over a short window |
| One IP per enabled AZ in DNS | An AZ with no healthy targets drops out of DNS when cross-zone is off. If all targets are unhealthy, the NLB fails open and returns all IPs |
| Security groups only if created with them | An NLB created without security groups can never have them. One created with them must always keep at least one |
| Distributed health checks | Targets see more checks than HealthCheckIntervalSeconds suggests (consensus across nodes). Fewer than expected usually means net.ipv4.tcp_tw_recycle is on: use tcp_tw_reuse |
| HTTP health check Host header | Contains the load balancer node's IP and the listener port, not the target's (an ALB sends the target's). Host-routed apps need a default host, a separate health port, or TCP checks |
| Idle timeout and resets | After the idle timeout, data on an old flow gets a TCP RST, as does traffic to a target that is failing but not yet marked unhealthy. TCP_ELB_Reset_Count spiking with UnhealthyHostCount means failing targets; a persistent rise without it means clients reusing expired flows (confirm in flow logs) |
| Port allocation (PrivateLink, or preservation off) | About 55,000 simultaneous connections, or about 55,000 per minute, to each unique target IP:port. Watch PortAllocationErrorCount and ActiveFlowCount. Add targets, or add up to 7 secondary IPs to the NLB's interfaces. That is irreversible: the IPs go only when the NLB is deleted |
| Duplicate flows (preservation on, plus cross-zone or several NLBs sharing a target IP:port, plus clients behind NAT) | Intermittent connection failures or delays. Increase the client or NAT source ports, add targets, change source ports on reconnect, or disable preservation |
| No IP fragments for non-UDP traffic | Fragmented TCP packets aren't routed |
Requests not reaching targets
- Security group on the targets (above) and on the NLB: the NLB's group must allow traffic to the targets.
- NACLs allow the listener and health ports both ways between NLB and target subnets.
- Targets are in an enabled AZ.
- Targets in a peered VPC must be registered by IP, not instance ID.
- QUIC listeners: the server ID configured on the target matches the target group's.
Provisioning fails
The NLB goes to failed if an IP it is given is already allocated elsewhere, for example as an instance's secondary IP. Free the IP and recreate.
TLS listeners
The backend TLS policy is chosen from the front-end one, as for ALBs: TLS 1.3 policies use ELBSecurityPolicy-TLS13-1-0-2021-06, post-quantum ones …-PQ-2025-09, FIPS ones the FIPS variants, and all others ELBSecurityPolicy-2016-08. Targets must present a certificate and ciphers that policy accepts. CloudFront VPC origins can't use an NLB with TLS listeners (patterns/cloudfront-to-alb.md).