A single HTTP/2 connection from a residential internet link can exhaust 32 GB of server memory in under 45 seconds. CVE-2026-49975 - the HTTP/2 Bomb - was discovered in May 2026 using OpenAI Codex, and it targets the ingress controllers, service meshes, and API gateways running in your Kubernetes clusters right now.

The situation for Kubernetes operators is more complex than mainstream coverage suggests. The most widely deployed ingress controller in the ecosystem was archived on March 24, 2026. It will never receive a patch for this vulnerability. Envoy - which backs Istio Gateway, Envoy Gateway, and kgateway - had a separate but related vulnerability (CVE-2026-47774) patched on June 3, 2026, the same day as this post. And exposure is not limited to public-facing ingress: service mesh sidecars, internal API gateways, and gRPC services face identical risk.

This guide covers the attack mechanics, per-controller hardening, detection patterns, and a concrete migration path.

What Is the HTTP/2 Bomb (CVE-2026-49975)?

Two Known Weaknesses, One New Attack

The HTTP/2 Bomb chains two well-documented HTTP/2 protocol behaviors into a memory exhaustion attack that bypasses every existing defense. Neither component is new. The combination is.

Step 1: HPACK indexed reference bomb. The attacker seeds the server’s HTTP/2 dynamic compression table (RFC 7541) with a single header entry. From that point on, a 1-byte index token (0xBE) references it in every subsequent request. The server allocates a full header structure for each reference regardless of content size. In NGINX, each reference creates a 59-byte ngx_table_elt_t struct allocation. Send enough references and memory fills up faster than connections are closed.

Step 2: Cookie header bypass. RFC 9113 Section 8.2.3 permits splitting HTTP cookies across multiple small header fields. Servers must reconstruct them before passing the request downstream. Apache’s reconstruction uses iterative string concatenation with pool allocation - each new fragment creates a string containing all previous fragments, and old strings persist until stream cleanup. This is quadratic growth. Envoy’s max_request_headers_kb limit checked only wire-encoded (compressed) bytes, not decoded totals, and excluded cookie fragment bytes from the header size count entirely.

Step 3: Flow control hold. The attacker sends SETTINGS with INITIAL_WINDOW_SIZE=0. The server cannot transmit DATA frames and buffers response bodies indefinitely. Sending WINDOW_UPDATE(increment=1) every 50 seconds resets NGINX’s 60-second send_timeout, pinning allocations for hours. A 150-byte 404 response can be held for approximately 2.3 hours; a 4 KB static file for approximately 62 hours.

sequenceDiagram
    participant A as Attacker
    participant S as Kubernetes Ingress

    A->>S: Seed HPACK table with single header entry
    Note over S: Dynamic table contains 1 entry

    loop Thousands of requests
        A->>S: 1-byte indexed reference (0xBE)
        Note over S: Server allocates full header struct per reference
    end

    A->>S: SETTINGS(INITIAL_WINDOW_SIZE=0)
    Note over S: Cannot transmit response data

    S-->>A: Response buffered, not sent

    loop Every 50 seconds
        A->>S: WINDOW_UPDATE(increment=1)
        Note over S: send_timeout reset, memory held for hours
    end

    Note over S: 32 GB exhausted<br/>NGINX: ~45s | Envoy: ~10s | Apache: ~18s

The three-step attack chain: HPACK table seeding, indexed reference flooding, and flow control hold combine to exhaust server memory without ever sending large payloads.

Why Amplification Ratios Vary by Server (70:1 to 5,700:1)

The per-server amplification ratios span more than two orders of magnitude because the root cause differs by implementation:

ServerAmplificationMemory ExhaustedTimeRoot Cause
Envoy 1.37.2~5,700:132 GB~10sCookie byte bypass + no decoded-size cap
Apache httpd 2.4.67~4,000:132 GB~18sQuadratic pool allocation in cookie merge
NGINX 1.29.7~70:132 GB~45sPer-header struct overhead, no cookie bypass
IIS (Windows Server 2025)~68:164 GB~45sKernel pool allocation per header pair via http.sys
Cloudflare Pingora 0.8.0~62:1N/AN/AUnlimited concurrent streams (Rust h2 crate default)

Envoy’s 5,700:1 ratio results from two compounding validation failures. Its max_request_headers_kb enforcement checked the wire-encoded (compressed) size rather than the decoded total. Cookie fragment bytes were excluded from header size accounting entirely and validated only after the size check passed. A single connection could accumulate decoded header data far beyond the configured limit before any defense triggered.

NGINX allocates a fixed 59-byte struct per header reference. No cookie bypass exists in NGINX’s implementation. Amplification is bounded by that per-struct overhead, which explains the 70x ratio compared to Envoy’s 5,700x.

The cookie fragmentation mechanism is what separates this attack from the 2016 HPACK Bomb (CVE-2016-6581). The older attack inflated header values directly, which modern servers block with decoded-size caps. CVE-2026-49975 attacks the per-entry bookkeeping overhead and exploits counting gaps in cookie fragment handling - neither of which the 2016 defenses address.

Envoy’s fix (in patched versions) now counts uncompressed cookie bytes toward mutable_max_request_headers_kb and max_headers_count, and resets HTTP/2 streams that violate the configured maximum header list size after decoding.

HTTP/2’s Track Record: A Pattern of Protocol-Level Attacks

CVE-2026-49975 is not an anomaly. HTTP/2’s stateful, multiplexed design has produced critical protocol-level attacks repeatedly over the last decade, each exploiting a different combination of the same protocol features.

Rapid Reset (CVE-2023-44487): 398 Million Requests Per Second

In October 2023, attackers discovered that HTTP/2’s stream multiplexing allowed rapid creation and cancellation of streams with practical effect. A server performs work on each stream before the RST_STREAM cancellation arrives. At scale, this generated request volumes that broke historical records: Google mitigated 398 million requests per second, Cloudflare 201 million rps, Amazon 155 million rps. Every major web server and proxy was affected. The attack consumed CPU rather than memory, and it required significant upstream bandwidth to execute.

Original HPACK Bomb (CVE-2016-6581) and Why Current Defenses Failed

The 2016 HPACK Bomb inflated large header values through HPACK compression. Servers responded by implementing decoded-size caps: reject any request whose headers decompress beyond a configured maximum size. CVE-2026-49975 bypasses this defense by attacking per-entry bookkeeping overhead rather than header value size, and by exploiting counting gaps in cookie fragment handling. The decoded-size cap that stopped the 2016 attack is architecturally irrelevant to the 2026 attack.

timeline
    title HTTP/2 Protocol-Level Vulnerabilities
    2016 : CVE-2016-6581 HPACK Bomb
         : Header value inflation via compression
         : Fixed with decoded-size caps
    2019 : CVE-2019-9517 Internal Data Buffering
         : TCP-HTTP/2 window mismatch forces buffering
         : Flow control related, no HPACK component
    2023 : CVE-2023-44487 Rapid Reset
         : Stream open/cancel causes CPU exhaustion
         : 398M rps measured against Google
    2026 : CVE-2026-49975 HTTP/2 Bomb
         : Per-entry overhead + cookie bypass + flow hold
         : Bypasses all defenses from 2016

Each attack exploits a different combination of HTTP/2’s core protocol features. Defenses for one attack do not prevent the next.

The Common Thread: Stateful Complexity Creates Attack Surface

HTTP/2’s design benefits - header compression, stream multiplexing, flow control - create state that must be tracked per connection, per stream, and per header table. Each piece of that state is an attack surface. Rapid Reset abused stream lifecycle. The 2016 HPACK Bomb abused header value encoding. CVE-2026-49975 abuses header table bookkeeping and cookie fragment counting. The protocol’s stateful complexity means this pattern is likely to continue.

Which Kubernetes Ingress Controllers Are Affected?

ingress-nginx Is Archived and Will Not Be Patched

The community ingress-nginx controller (kubernetes/ingress-nginx) was archived on March 24, 2026. No further releases, bug fixes, or security patches will come from the project. Over 40% of Kubernetes clusters were running ingress-nginx at the time of its retirement.

This creates a concrete operational gap: clusters running ingress-nginx will not receive a CVE-2026-49975 patch through the project. Operators have three options:

  1. Rebuild the container image with NGINX >= 1.29.8 (the patched version that introduced max_headers)
  2. Migrate to NGINX Gateway Fabric (which bundles a current NGINX release)
  3. Switch to a different Gateway API implementation

There is no fourth option where a patch arrives through normal channels.

Envoy-Based Controllers (Envoy Gateway, Istio, kgateway)

Envoy’s vulnerability was tracked as CVE-2026-47774 (GHSA-22m2-hvr2-xqc8) - a separate CVE from the base Apache httpd CVE-2026-49975, but the same attack class. Envoy published its advisory on June 3, 2026 with patched versions 1.35.11, 1.36.7, 1.37.3, and 1.38.1.

Controllers using Envoy as the data plane all share this requirement:

  • Envoy Gateway - upgrade to a release bundling Envoy >= 1.35.11 / 1.36.7 / 1.37.3 / 1.38.1
  • Istio Gateway - same Envoy version requirements; check your Istio release’s bundled Envoy version specifically
  • kgateway (formerly Gloo Gateway, CNCF) - same Envoy patching requirements

NGINX Gateway Fabric

NGINX Gateway Fabric is the supported migration path for ingress-nginx users. It bundles a current NGINX release and implements the Gateway API. Since the CVE-2026-49975 fix landed in NGINX 1.29.8, verify the bundled NGINX version in your running pods is at or above that release:

# Verify the NGINX version bundled in your Gateway Fabric deployment
kubectl exec -n nginx-gateway deploy/nginx-gateway-fabric -- nginx -v

# Confirm max_headers is present in the active config (added in 1.29.8)
kubectl exec -n nginx-gateway deploy/nginx-gateway-fabric -- nginx -T 2>/dev/null | grep max_headers

HAProxy: Architecturally Immune

HAProxy Kubernetes Ingress Controller is architecturally resistant to both the HTTP/2 Bomb and Rapid Reset attacks. The design difference is fundamental: HAProxy tracks allocated resources rather than just established connections. Closed streams still count against concurrency limits until fully released. New stream creation queues when limits are reached rather than allocating memory speculatively.

Under simulated attack conditions, HAProxy was tested to 800,000 requests per second without degradation. This is a design-level property, not a patch applied after discovery.

The Internal Exposure You Are Missing

Shodan identified 880,000+ public-facing HTTP/2 termination points. That figure excludes:

  • Service mesh sidecars - Every Envoy sidecar in an Istio mesh terminates HTTP/2 between pods. An attacker with access to any pod can target adjacent services through their sidecars.
  • Internal API gateways - Not internet-facing, but reachable from inside the cluster or corporate network.
  • gRPC services - gRPC uses HTTP/2 as its transport. Any gRPC service running unpatched NGINX or Envoy is vulnerable.
  • CDN-fronted origins - CDNs terminate HTTP/2 and re-establish connections to origin. This provides partial protection, but only if the CDN itself is not vulnerable. Cloudflare Pingora 0.8.0 has no confirmed patch as of June 4, 2026.
graph TD
    A[External Client] -->|HTTP/2| B[CDN or WAF Layer]
    B -->|HTTP/2 re-established| C[Kubernetes Ingress Controller]
    C --> D[Service A Pod]
    C --> E[Service B Pod]
    D <-->|HTTP/2 via sidecar| F[Envoy Sidecar A]
    E <-->|HTTP/2 via sidecar| G[Envoy Sidecar B]
    F -->|Internal HTTP/2| H[Internal API Gateway]
    H --> I[gRPC Service]

    style C fill:#d0021b,color:#fff
    style F fill:#d0021b,color:#fff
    style G fill:#d0021b,color:#fff
    style H fill:#d0021b,color:#fff
    style I fill:#d0021b,color:#fff
    style B fill:#f5a623,color:#000

CVE-2026-49975 exposure runs through the entire HTTP/2 path inside a Kubernetes cluster, not just public-facing ingress. Red components require patching; orange may provide partial mitigation depending on vendor status.

Hardening Guide: Per-Controller HTTP/2 Configuration

NGINX / NGINX Gateway Fabric

For clusters still running ingress-nginx, verify the NGINX binary version first:

# Must be >= 1.29.8 to have the max_headers directive
kubectl exec -n ingress-nginx deploy/ingress-nginx-controller -- nginx -v

# Verify max_headers appears in the active configuration
kubectl exec -n ingress-nginx deploy/ingress-nginx-controller -- \
  nginx -T 2>/dev/null | grep -E 'http2|max_headers'

Apply hardening settings via ConfigMap while you plan migration to a supported controller:

apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  use-http2: "true"
  http2-max-concurrent-streams: "64"      # default: 128
  large-client-header-buffers: "4 8k"
  client-header-buffer-size: "1k"

If the running NGINX version is below 1.29.8, set use-http2: "false" as an emergency mitigation. This eliminates the attack vector entirely while you rebuild the image with an updated NGINX binary or complete migration.

NGINX 1.29.8 introduced the max_headers directive (default: 1,000 headers). This limits the number of header references that can accumulate, bounding the HPACK amplification. Current NGINX stable is 1.30.2, which includes the same fix.

Envoy / Istio Gateway / Envoy Gateway

Apply HTTP/2 hardening via an EnvoyFilter after upgrading to a patched Envoy version. These settings reduce the attack window but do not fully substitute for patching - pre-patch Envoy’s cookie byte bypass bypasses these limits regardless of their values.

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: http2-hardening
  namespace: istio-system
spec:
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: envoy.filters.network.http_connection_manager
    patch:
      operation: MERGE
      value:
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          http2_protocol_options:
            max_concurrent_streams: 64
            initial_stream_window_size: 1048576      # 1 MiB (default: 16 MiB)
            initial_connection_window_size: 2097152  # 2 MiB (default: 24 MiB)
            max_outbound_frames: 5000
            max_outbound_control_frames: 500
            max_inbound_window_update_frames_per_data_frame_sent: 10

Key settings and why they matter:

  • max_concurrent_streams: 64 reduces the number of streams an attacker can hold simultaneously from the default 1,024
  • initial_stream_window_size: 1048576 limits per-stream response buffering, reducing the hold duration once the flow control attack activates
  • max_inbound_window_update_frames_per_data_frame_sent: 10 mitigates the periodic WINDOW_UPDATE(1) keepalive pattern that resets send timeouts

Verify the Envoy version running in your mesh:

# Check Envoy version in Istio ingress gateway
kubectl exec -n istio-system deploy/istio-ingressgateway \
  -- pilot-agent request GET /server_info | grep version

Emergency Mitigation: Disabling HTTP/2

If immediate patching is not possible and you need a same-day mitigation, disabling HTTP/2 eliminates the attack vector entirely:

# ingress-nginx ConfigMap patch
apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  use-http2: "false"

The performance trade-off: HTTP/1.1 lacks request multiplexing, header compression, and stream prioritization. For most production workloads behind a CDN, the user-visible impact is minimal. For high-throughput API endpoints that rely heavily on multiplexing, plan the emergency mitigation window around lower-traffic periods.

Detecting HTTP/2 Protocol Abuse in Production

Memory and Connection Indicators

The HTTP/2 Bomb is a memory exhaustion attack. The primary observable signal is RSS growth that does not correlate with request volume.

Memory-based indicators:

  • Sustained RSS or virtual memory growth in NGINX or Envoy worker processes without corresponding increases in request rate
  • NGINX-specific: memory does not reclaim after connections close. Peak RSS of 1.41 GB may drop only to 1.13 GB after attack traffic ends due to glibc ptmalloc heap fragmentation. Worker process restart is required to fully reclaim memory.
  • kubectl get events --all-namespaces --field-selector reason=OOMKilling showing ingress controller pods

Connection-based indicators:

  • Extended HTTP/2 connections with near-zero data transfer rates after the initial request phase (the flow control hold pattern)
  • Stalled streams with approximately 34 bytes per second of traffic (the WINDOW_UPDATE(1) keepalive pattern)
  • Header field counts exceeding 1,000 per request; normal requests rarely exceed 50-100

Prometheus Alerts for Ingress Controllers

# Memory growth alert: > 100 MB growth over 5 minutes in the ingress controller container
rate(container_memory_working_set_bytes{
  namespace="ingress-nginx",
  container="controller"
}[5m]) > 100000000

# Envoy connection accumulation without request growth
# Ratio > 0.5 indicates many open connections with few active requests
envoy_http_downstream_cx_active / envoy_http_downstream_rq_total > 0.5

# Envoy server memory growth rate
rate(envoy_server_memory_allocated[5m]) > 50000000

Add nginx_connections_active from the NGINX Prometheus Exporter if you are running it. Spikes without corresponding request rate increases indicate connection-hold patterns consistent with HTTP/2 attacks.

WAF Rules for Header Field Count Limits

Cap the maximum header field count at the network edge before traffic reaches your ingress controller. The HTTP/2 Bomb requires thousands of header references to be effective. Legitimate requests do not exceed 100-200 headers. Most commercial WAFs and CDN providers expose header count limits as configurable thresholds.

Alert on sustained WINDOW_UPDATE traffic with increment values near 1 over multi-minute windows. This pattern is a reliable signal of the flow control hold step of the attack.

The Bigger Picture: AI-Assisted Vulnerability Discovery

Researcher Quang Luong discovered CVE-2026-49975 using OpenAI Codex. The method matters: Codex did not identify a new class of vulnerability. It recognized that two known vulnerability primitives - HPACK amplification (CVE-2016-6581) and Slowloris-style flow control holds (CVE-2016-8740) - combined into something more severe than either alone. As the Calif blog described it: “two publicly known halves compose” into something “obvious once you see it” that had escaped human researchers for a decade.

After NGINX and Apache released patches with visible code diffs, Luong used Codex to reverse-engineer the vulnerability from the patch commits. This confirmed that Envoy, IIS, and Pingora were also affected by the same underlying weakness - a separate confirmation step that human researchers rarely perform systematically.

This approach - exhaustive compositional analysis of known vulnerability primitives - is where AI excels and humans do not. A human researcher reads vulnerability disclosures sequentially and applies one fix at a time. An AI system can hold hundreds of known patterns simultaneously and test their combinations at a speed that makes systematic coverage practical.

The practical implication for your threat model: known vulnerabilities in your dependencies are no longer simply “known.” They are inputs to an automated composition process that may produce novel attacks faster than patches ship.

Action Plan: Patch, Harden, Migrate

Immediate (This Week)

  • Verify Envoy versions. Confirm all Envoy-based controllers and sidecars are on >= 1.35.11, 1.36.7, 1.37.3, or 1.38.1. CVE-2026-47774 was patched June 3, 2026.
  • Check your ingress-nginx NGINX binary version. Run kubectl exec -n ingress-nginx deploy/ingress-nginx-controller -- nginx -v. If the version is below 1.29.8, apply the emergency ConfigMap hardening or disable HTTP/2 immediately.
  • Audit internal HTTP/2 exposure. Inventory every component in your cluster that terminates HTTP/2: Envoy sidecars, internal gateways, gRPC services.

Short-Term (This Quarter)

  • Migrate off archived ingress-nginx. No patch pathway exists through the project. Plan and execute migration to a supported Gateway API implementation using ingress2gateway v1.0.0.
  • Apply Envoy HTTP/2 hardening. Whether or not you have patched, lower max_concurrent_streams to 64 and reduce window sizes on ingress-facing listeners.
  • Deploy memory growth and connection accumulation alerts. The Prometheus queries above provide early warning before an attack exhausts resources.

Strategic (Gateway API Migration)

The ingress-nginx retirement forces a Gateway API migration that was already the recommended path. Ingress2gateway v1.0.0 (March 2026) handles 30+ common ingress-nginx annotation conversions automatically. When selecting an implementation, the HTTP/2 security track record is a concrete evaluation criterion:

ControllerCVE-2026-49975CVE-2023-44487Recommended Action
ingress-nginxNo patch (archived)PatchedMigrate immediately
NGINX Gateway FabricPatched (NGINX >= 1.29.8)PatchedVerify bundled NGINX version
Envoy GatewayPatched (Envoy >= 1.35.11)PatchedUpgrade to patched Envoy release
Istio GatewayPatched (Envoy >= 1.35.11)PatchedUpgrade to patched Envoy release
HAProxy IngressArchitecturally immuneArchitecturally immuneStrong choice for security-critical environments

HAProxy’s design-level resistance to both HTTP/2 attack classes is documented and tested. If HTTP/2 security posture is a primary factor in your ingress selection, it is a meaningful differentiator worth evaluating alongside operational familiarity and ecosystem integrations.

Frequently Asked Questions

Can the HTTP/2 Bomb attack reach my internal Kubernetes services, not just public-facing ingress?

Yes. Any component that terminates HTTP/2 is vulnerable, including service mesh sidecars (Envoy in Istio), internal API gateways, and gRPC services. An attacker with access to any pod in the mesh can target adjacent services through their Envoy sidecars. The 880,000+ public servers identified via Shodan represent only the internet-facing fraction of the total vulnerable surface.

My cluster runs ingress-nginx. Will it get a patch for CVE-2026-49975?

No. The community ingress-nginx project (kubernetes/ingress-nginx) was archived on March 24, 2026, and receives no further security patches. Your options are rebuilding the container image with NGINX >= 1.29.8, migrating to NGINX Gateway Fabric, or switching to another supported Gateway API implementation. No patch will arrive through normal ingress-nginx project channels.

Should I disable HTTP/2 on my ingress controller as an emergency mitigation?

If you cannot patch immediately, disabling HTTP/2 eliminates the attack vector entirely. Set use-http2: "false" in the ingress-nginx ConfigMap, or disable HTTP/2 on Envoy downstream listeners. The trade-off is losing HTTP/2 performance benefits - request multiplexing, header compression, stream prioritization - until you can patch and re-enable. For most workloads behind a CDN, the visible impact is low. For high-throughput API endpoints that rely on multiplexing, plan the mitigation window around lower-traffic periods.

Why is Envoy’s amplification ratio (5,700:1) so much higher than NGINX’s (70:1)?

Envoy had two compounding validation failures: its max_request_headers_kb limit checked only wire-encoded (compressed) bytes rather than decoded totals, and cookie fragment bytes were excluded from header size accounting entirely. A connection could accumulate decoded header data far beyond the configured limit before any defense triggered. NGINX allocates a fixed 59-byte struct per header reference with no cookie bypass, so amplification is bounded by that per-struct overhead alone. Patched Envoy versions now count uncompressed cookie bytes toward header size limits and enforce decoded header size caps in the oghttp2 and quiche HPACK processing paths.

Is HAProxy immune to the HTTP/2 Bomb, and should I switch to it?

HAProxy is architecturally resistant to both the HTTP/2 Bomb and Rapid Reset attacks. Its concurrency model tracks allocated resources rather than just established connections, so stalled or closed streams count against limits until fully released. New stream creation queues when limits are reached rather than allocating memory speculatively. This is a design property, not a retroactive patch. If you are evaluating ingress controllers as part of the Gateway API migration and HTTP/2 security posture is a priority, HAProxy’s documented architectural immunity is a concrete differentiator.