Describe the bug:
I’m using the GKE Gateway controller on a GKE cluster with cert-manager installed via the official chart. I’m using:
- 1 gateway in the
integrationnamespace calledintegrationlooking like this:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-staging
networking.gke.io/addresses: ""
networking.gke.io/backend-services: /projects/000000000000/regions/europe-west3/backendServices/gkegw1-b35h-integration-gw-serve404-80-um3p00uxr7bf,
/projects/000000000000/regions/europe-west3/backendServices/gkegw1-b35h-integration-gw-serve500-80-w8426ytw9ck4
networking.gke.io/firewalls: /projects/000000000000/global/firewalls/gkegw1-b35h-l7-default-europe-west3
networking.gke.io/forwarding-rules: /projects/000000000000/regions/europe-west3/forwardingRules/gkegw1-b35h-integration-integration-q41c4s983fgr
networking.gke.io/health-checks: /projects/000000000000/regions/europe-west3/healthChecks/gkegw1-b35h-integration-gw-serve404-80-um3p00uxr7bf,
/projects/000000000000/regions/europe-west3/healthChecks/gkegw1-b35h-integration-gw-serve500-80-w8426ytw9ck4
networking.gke.io/last-reconcile-time: "2026-03-09T14:52:15Z"
networking.gke.io/lb-edge-extensions: ""
networking.gke.io/lb-route-extensions: ""
networking.gke.io/lb-traffic-extensions: ""
networking.gke.io/ssl-certificates: ""
networking.gke.io/target-http-proxies: /projects/000000000000/regions/europe-west3/targetHttpProxies/gkegw1-b35h-integration-integration-os2neyue7uw5
networking.gke.io/target-https-proxies: ""
networking.gke.io/url-maps: /projects/000000000000/regions/europe-west3/urlMaps/gkegw1-b35h-integration-integration-os2neyue7uw5
networking.gke.io/wasm-plugin-versions: ""
networking.gke.io/wasm-plugins: ""
name: integration
namespace: integration
spec:
addresses:
- type: NamedAddress
value: gke-gateway-address
gatewayClassName: gke-l7-regional-external-managed
listeners:
- allowedRoutes:
namespaces:
from: All
hostname: example.com
name: http
port: 80
protocol: HTTP
- allowedRoutes:
namespaces:
from: All
hostname: example.com
name: https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: tls-cert-example-com
namespace: integration
mode: Terminate
status:
addresses:
- type: IPAddress
value: 1.1.1.1 (changed ofc)
conditions:
- lastTransitionTime: "2026-03-09T14:48:40Z"
message: The OSS Gateway API has deprecated this condition, do not depend on it.
observedGeneration: 40
reason: Scheduled
status: "True"
type: Scheduled
- lastTransitionTime: "2026-03-09T14:48:40Z"
message: ""
observedGeneration: 40
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2026-03-09T14:49:14Z"
message: ""
observedGeneration: 40
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: "2026-03-09T14:49:14Z"
message: The OSS Gateway API has altered the "Ready" condition semantics and reserved
it for future use. GKE Gateway will stop emitting it in a future update, use
"Programmed" instead.
observedGeneration: 40
reason: Ready
status: "True"
type: Ready
- lastTransitionTime: "2026-03-09T14:49:14Z"
message: ""
observedGeneration: 40
reason: Healthy
status: "True"
type: networking.gke.io/GatewayHealthy
listeners:
- attachedRoutes: 0
conditions:
- lastTransitionTime: "2026-03-09T14:48:40Z"
message: ""
observedGeneration: 40
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
- lastTransitionTime: "2026-03-09T14:48:40Z"
message: ""
observedGeneration: 40
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2026-03-09T14:49:14Z"
message: ""
observedGeneration: 40
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: "2026-03-09T14:49:14Z"
message: The OSS Gateway API has altered the "Ready" condition semantics and
reserved it for future use. GKE Gateway will stop emitting it in a future
update, use "Programmed" instead.
observedGeneration: 40
reason: Ready
status: "True"
type: Ready
name: http
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- 1 ClusterIssuer:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-staging
server: https://acme-staging-v02.api.letsencrypt.org/directory
solvers:
- http01:
gatewayHTTPRoute:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: integration
namespace: integration
sectionName: http
selector:
dnsNames:
- example.com
The external regional ALB is correctly provisioned, the gateway is marked as programmed and its status looks ok. The HTTPRoute that gets automatically created by the ClusterIssuer also looks ok. Except that the HTTP01 challenge remains forever stuck in the “pending” status with the reason “Waiting for HTTP-01 challenge propagation: wrong status code ‘404’, expected ‘200’”.
I debugged further by creating an additional HTTPRoute object in the same namespace referring to an actual app (outside of this debugging step, I do not have any HTTPRoute in place because I first want to test the behavior of the provisioning of certificates). Sure enough, minutes after, the route actually does work and I can reach the app from outside the cluster, as expected.
Something else I’ve tried was to port-forward through the solver pod and do a GET call on the token endpoint like this: http://localhost:8089/.well-known/acme-challenge/token -H “Host: example.com” → sure enough, this also works.
When I do a curl on the token endpoint from outside the cluster I get “fault filter abort” returned, which afaik means nothing is available on that route.
→
Expected behaviour:
The challenge is not stuck in the “pending” status and the certificate gets correctly provisioned. The HTTPRoute is also attached to the Gateway.
Steps to reproduce the bug:
- Have a GKE standard cluster with Gateway API enabled
- Install cert-manager
- Create a Gateway in a given namespace with the “gke-l7-regional-external-managed” gateway class name and annotate it with
cert-manager.io/cluster-issuer: letsencrypt-staging - Configure a ClusterIssuer named
letsencrypt-staging(e.g. with the staging endpoint) with a HTTP01 solver referring to the previously created Gateway object - See the challenge stuck in the pending status
Anything else we need to know?:
- “Attached routes” show 0 on the Gateway but I didn’t check if that was different when I manually tested a user-defined HTTPRoute object connected to an app running in the namespace.
Environment details:
- Kubernetes version: v1.33.5-gke.2392000
- cert-manager version: 1.19.4 (gateway api enabled)
I had created a github issue in the cert-manager repository but seems like the issue does not come from their side but rather from the GKE Gateway controller? Has anybody faced a similar issue with a similar setup?