Please use this template for troubleshooting questions.
My issue:
cannot figure out how to expose /readyz to my AWS Target Group’s Health Check, /readyz on port 8081 is exposed in the cluster, but the worker node is not exposing /readyz for the AWS Target Group Health Check to be successful.
How I encountered the problem:
installing NGF for the first time
Working Solution:
Here’s a minimal hashicorp/http-echo backend plus the HTTPRoute for ALB health checks. This puts everything in nginx-gateway so it is easy to manage with the shared gateway.
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway-healthcheck
namespace: nginx-gateway
labels:
app: gateway-healthcheck
spec:
replicas: 2
selector:
matchLabels:
app: gateway-healthcheck
template:
metadata:
labels:
app: gateway-healthcheck
spec:
containers:
- name: http-echo
image: hashicorp/http-echo:1.0.0
args:
- "-listen=:5678"
- "-text=ok"
ports:
- containerPort: 5678
name: http
readinessProbe:
httpGet:
path: /
port: 5678
initialDelaySeconds: 2
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: 5678
initialDelaySeconds: 5
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: gateway-healthcheck
namespace: nginx-gateway
labels:
app: gateway-healthcheck
spec:
selector:
app: gateway-healthcheck
ports:
- name: http
port: 80
targetPort: 5678
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: gateway-healthcheck
namespace: nginx-gateway
spec:
parentRefs:
- name: nginx-gateway
namespace: nginx-gateway
rules:
- matches:
- path:
type: Exact
value: /healthz
backendRefs:
- name: gateway-healthcheck
port: 80
Then set the ALB target group health check to:
Version of NGF and/or NGINX:
2.5.1
Deployment environment:
test
What I am asking the community, is there an easier way to accomplish this?
@beergeek303 Are you wanting the /readyz endpoint on the gateway to be exposed on the LoadBalancer Service? If so, you can update the NginxProxy CRD with the following config to expose the readiness port on the Service
spec:
kubernetes:
deployment:
container:
readinessProbe:
expose: true
References:
No, we don’t use the Load Balancer Service. We have an already deployed ALB, we only add in a listener that points to the target group for the node port.
Here is our Helm values we pass in:
nginx:
kind: daemonSet
config:
ipFamily: ipv4
service:
type: NodePort
nodePorts:
- port: 32323
listenerPort: 80
gateways:
- name: nginx-gateway
namespace: nginx-gateway
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
The setup is working, but we are looking the best approach for allowing the target group to monitor readyz.
Do you just need the readyz 8081 port exposed on the NodePort Service then? (shouldn’t matter LB vs NodePort)
In the helm values, what if you set
nginx:
container:
readinessProbe:
expose: true
We have add this config:
nginx:
kind: daemonSet
config:
ipFamily: ipv4
container:
readinessProbe:
expose: true
service:
type: NodePort
nodePorts:
- port: 32323
listenerPort: 80
gateways:
- name: nginx-gateway
namespace: nginx-gateway
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
We can get a response back from a data plane pod:
❯ curl -i http://10.XX.XX.XX:8081/readyz
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 14 Apr 2026 20:15:25 GMT
Content-Type: application/octet-stream
Content-Length: 0
Connection: keep-alive
But when we try to get a response back from the node using the node port, the same node the data plane pod resides on:
❯ curl -i http://10.XX.XX.XX:32323/readyz
HTTP/1.1 404 Not Found
Server: nginx
Date: Tue, 14 Apr 2026 20:39:12 GMT
Content-Type: text/html
Content-Length: 146
Connection: keep-alive
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
What we are ultimately trying to accomplish here is to get a health check endpoint for the nginx proxy.
This works in ingess-nginx currently for /healthz. Just looking for similar functionality to help others as well who will bump into this potentially. Thanks for your support.
I see now, the NodePort you configured maps to port 80 on the Service, not 8081 where the /readyz endpoint is exposed.
What if in your Service nodeport config you add:
service:
type: NodePort
nodePorts:
- port: 32323
listenerPort: 80
- port: 32324
listenerPort: 8081
That worked! We were used to both being on the same port, but now they are different (80/8081). We updated out AWS Target Group Health Check to check 32324 now and it works. We did validate we did need the expose: true for this to work as well.
Glad to hear it!
We were used to both being on the same port, but now they are different
Yes, the current setup is that only the paths that are defined in HTTPRoutes get exposed on the ports defined in the Gateway Listeners that those Routes are attached to. We don’t create an extra /readyz endpoint on those ports, because they are owned by the Listeners/HTTPRoutes. So we expose it on a separate port that won’t conflict with anything that might be defined in an HTTPRoute.