I am testing the new Gateway Load Balancer TCP Reset feature (announced 2026-09-02) but cannot get a TCP Reset to fire on target unhealthy. The CloudWatch metric TCP_ELB_Reset_Count (AWS/GatewayELB) stays 0 across all attempts.
Environment (single AZ, ap-northeast-1a):
- GWLB with one target group (GENEVE/6081), target type instance, one EC2 appliance target
- The appliance is a self-managed Amazon Linux 2023 EC2 doing GENEVE hairpin via iptables (DNAT/MASQUERADE on ens5), based on the AWS re:Post article "How do I use iptables to test a Gateway Load Balancer that has an Amazon EC2 instance as a target?"
- A client EC2 in a separate subnet routes 0.0.0.0/0 to a GWLB endpoint (GWLBE) placed in the appliance subnet (which has 0.0.0.0/0 to a NAT Gateway). The full inspection path works: client curl to an internet host returns 200 via the NAT Gateway public IP.
Target group attributes:
- send_tcp_reset.on_unhealthy.enabled = true
- target_failover.on_unhealthy = no_rebalance
- target_failover.on_deregistration = no_rebalance
- stickiness.enabled = false (so effective flow stickiness is 5-tuple)
- Health check: TCP:80, interval 5s, healthy threshold 5, unhealthy threshold 2
Listener attributes:
- send_tcp_reset.on_idle_timeout.enabled = false
- tcp.idle_timeout.seconds = 350
What I did:
- Started the appliance service so the target is healthy.
- From the client, opened one long-lived TCP flow through the GWLBE to an external host (nc to an SSH server on port 22), confirmed ESTABLISHED with ss and confirmed the 3-way handshake in tcpdump on the client.
- Stopped the health check listener (httpd on :80) so the target became unhealthy (confirmed via describe-target-health, Target.FailedHealthChecks) about 10s later.
- Sent additional (non-SYN) data on the existing flow from the client.
Observed:
- The packet still reaches the destination and gets a normal ACK, i.e. the flow keeps being forwarded through the unhealthy target (fail-open, as documented for existing flows).
- No RST is returned by GWLB. TCP_ELB_Reset_Count remains 0.
I also tried a second variant: after the target became unhealthy, I additionally removed the iptables DNAT/MASQUERADE rules on the appliance so packets are no longer hairpinned. In tcpdump the client just retransmits the same segment with exponential backoff and receives nothing back — still no RST from GWLB.
Questions:
- With no_rebalance + send_tcp_reset.on_unhealthy.enabled = true and 5-tuple stickiness, what exactly triggers the RST? Does GWLB require the incoming packet to actually reach the GWLB data plane, and does a self-managed iptables hairpin appliance interfere with RST generation?
- Is there any additional prerequisite (listener setting, appliance behavior, GENEVE handling) for on_unhealthy RST beyond the target being marked unhealthy and receiving a non-SYN packet on an existing flow?
- Is a self-managed iptables-based appliance a supported configuration for observing this feature, or is a real inspection appliance required?
Region: ap-northeast-1.
Best Regards,
Sum