Skip to content

[Gateway API] HTTP Listener fails when Service has appProtocol: kubernetes.io/h2c #4497

@starlightromero

Description

@starlightromero

What happened?

When using Gateway API with HTTPRoutes that include HTTP redirect-only routes (no backend refs, only requestRedirect filter), the AWS Load Balancer Controller fails to deploy the Gateway when the target Service has appProtocol: kubernetes.io/h2c configured.

The controller creates an HTTP/2 target group for the HTTP listener (port 80), which AWS ALB does not support. ALBs only support HTTP/2 (h2c) on HTTPS listeners (port 443).

Error Message

Warning  FailedDeployModel  gateway.k8s.aws/alb  
Failed deploy model due to operation error Elastic Load Balancing v2: ModifyRule, 
https response error StatusCode: 400, RequestID: a4d2979b-d87e-436f-8141-71e7b19bcd88, 
InvalidLoadBalancerAction: Listener protocol 'HTTP' is not supported with a target group with the protocol-version 'HTTP2'

Expected Behavior

One of the following should happen:

  1. Preferred: HTTP redirect-only routes (with no backendRefs, only requestRedirect filter) should NOT create target groups at all since they don't route to backends
  2. Alternative: HTTP listeners should create HTTP/1.1 target groups even when the referenced service has appProtocol: kubernetes.io/h2c, since h2c is only valid on HTTPS listeners per AWS ALB limitations

AWS ALB h2c Support

AWS ALBs do support HTTP/2 cleartext (h2c), but with important constraints:

  • HTTPS listeners (port 443): Can use target groups with ProtocolVersion: HTTP2
  • HTTP listeners (port 80): Cannot use target groups with ProtocolVersion: HTTP2

Reference: AWS ALB Target Group Protocol Versions

Steps to Reproduce

1. Create a Service with appProtocol: kubernetes.io/h2c

apiVersion: v1
kind: Service
metadata:
  name: keda-add-ons-http-interceptor-proxy
  namespace: keda-system
spec:
  ports:
  - appProtocol: kubernetes.io/h2c
    name: proxy
    port: 8080
    protocol: TCP
    targetPort: proxy
  selector:
    app: keda-add-ons-http-interceptor

2. Create Gateway with HTTP and HTTPS listeners

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: alb-private
  namespace: aws-system
spec:
  gatewayClassName: aws-alb
  listeners:
  - name: dev-app-http
    hostname: dev.app.example.internal
    port: 80
    protocol: HTTP
  - name: dev-app-https
    hostname: dev.app.example.internal
    port: 443
    protocol: HTTPS
    tls:
      certificateRefs:
      - group: acm.services.k8s.aws
        kind: Certificate
        name: dev.app.example.com

3. Create HTTPRoute for HTTPS traffic to h2c backend

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: dev-app
  namespace: dev-app
spec:
  hostnames:
  - dev.app.example.internal
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: alb-private
    namespace: aws-system
    sectionName: dev-app-https
  rules:
  - backendRefs:
    - group: ""
      kind: Service
      name: keda-add-ons-http-interceptor-proxy
      namespace: keda-system
      port: 8080
    matches:
    - path:
        type: PathPrefix
        value: /

4. Create HTTPRoute for HTTP → HTTPS redirect (NO backend refs)

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: dev-app-redirect
  namespace: dev-app
spec:
  hostnames:
  - dev.app.example.internal
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: alb-private
    namespace: aws-system
    sectionName: dev-app-http
  rules:
  - filters:
    - requestRedirect:
        scheme: https
        statusCode: 301
      type: RequestRedirect
    matches:
    - path:
        type: PathPrefix
        value: /

Result

  • HTTPS Route (dev-app): Creates target group with ProtocolVersion: HTTP2 ✅ Works correctly
  • HTTP Redirect Route (dev-app-redirect): Controller tries to create target group with ProtocolVersion: HTTP2 ❌ Fails with error
  • Gateway Status: All listeners show Attached Routes: 0, no targets registered

Environment

  • AWS Load Balancer Controller Version: v2.16.0
  • Kubernetes Version: v1.34
  • AWS Region: us-east-1
  • Gateway API Version: v1

Workaround

Currently, we must choose one of:

  1. Remove HTTP redirect HTTPRoutes (lose redirect functionality)
  2. Remove appProtocol: kubernetes.io/h2c from service (lose HTTP/2 h2c benefits on HTTPS)
  3. Use ALB listener rules directly instead of Gateway API for redirects

Additional Context

The HTTPS route works perfectly with h2c - the issue is specifically with HTTP listeners trying to use HTTP/2 target groups, which AWS does not support. Redirect-only routes should not create target groups since they don't route traffic to backends.

This appears to be related to how the controller determines target group protocol version based on service appProtocol, without considering whether the listener protocol supports it.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions