-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
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:
- Preferred: HTTP redirect-only routes (with no
backendRefs, onlyrequestRedirectfilter) should NOT create target groups at all since they don't route to backends - 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-interceptor2. 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.com3. 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:
- Remove HTTP redirect HTTPRoutes (lose redirect functionality)
- Remove
appProtocol: kubernetes.io/h2cfrom service (lose HTTP/2 h2c benefits on HTTPS) - 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.