---
cuppy_hub: aws
cuppy_path: reference/elb/nlb.md
cuppy_section: docs
cuppy_doc: QER9-JPQ9
cuppy_doc_uuid: 95c8f994-032f-4021-b65a-8ccd3b197707
cuppy_permalink: https://cuppy.io/aws/d/QER9-JPQ9
cuppy_version: 4
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/aws/docs/reference/elb/nlb
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 5734a3dbf368b60cf8040cce582df01576bd62cb7c21ebf3bd7d8160c4c7be12
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Network Load Balancer behaviour and failures

**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

1. Security group on the targets (above) and on the NLB: the NLB's group must allow traffic to the targets.
2. NACLs allow the listener and health ports **both ways** between NLB and target subnets.
3. Targets are in an **enabled** AZ.
4. Targets in a **peered VPC** must be registered by IP, not instance ID.
5. 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`).


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 131 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/aws/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
