Response headers
Use the ResponseHeaderModifier
filter to add, append, overwrite, or remove headers from a response before it is sent back to the client.
For more information, see the HTTPHeaderFilter specification.
Before you begin
-
Follow the Get started guide to install kgateway.
-
Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.
-
Get the external address of the gateway and save it in an environment variable.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESS
kubectl port-forward deployment/http -n kgateway-system 8080:8080
Add response headers
Add headers to incoming requests before they are sent back to the client. If the response already has the header set, the value of the header in the ResponseHeaderModifier
filter is appended to the value of the header in the response.
-
Set up a header modifier that adds a
my-response: hello
response header. Choose between the HTTPRoute for a Gateway API-native way, or TrafficPolicy for more flexible attachment options such as a gateway-level policy.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-headers namespace: httpbin spec: parentRefs: - name: http namespace: kgateway-system hostnames: - headers.example rules: - filters: - type: ResponseHeaderModifier responseHeaderModifier: add: - name: my-response value: hello backendRefs: - name: httpbin port: 8000 EOF
Setting Description spec.parentRefs
The name and namespace of the gateway that serves this HTTPRoute. In this example, you use the http
gateway that was created as part of the get started guide.spec.rules.filters.type
The type of filter that you want to apply to incoming requests. In this example, the ResponseHeaderModifier
filter is used.spec.rules.filters.responseHeaderModifier.add
The name and value of the response header that you want to add. spec.rules.backendRefs
The backend destination you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide. Note: The steps in this section use the Envoy-based kgateway proxy. The steps do not work with the agentgateway proxy.
-
Create an HTTPRoute resource for the route that you want to modify. Note that the example selects the http Gateway that you created before you began.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-headers namespace: httpbin spec: parentRefs: - name: http namespace: kgateway-system hostnames: - headers.example rules: - backendRefs: - name: httpbin port: 8000 EOF
-
Create a TrafficPolicy that adds a
my-response: hello
header to a response. The following example attaches the TrafficPolicy to the http Gateway.kubectl apply -f- <<EOF apiVersion: gateway.kgateway.dev/v1alpha1 kind: TrafficPolicy metadata: name: httpbin-headers namespace: kgateway-system spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: http headerModifiers: response: add: - name: my-response value: hello EOF
-
-
Send a request to the httpbin app on the
headers.example
domain. Verify that you get back a 200 HTTP response code and that you see themy-response
header in the response.curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers -H "host: headers.example:8080"
curl -vi localhost:8080/response-headers -H "host: headers.example"
Example output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
* Mark bundle as not supporting multiuse < HTTP/1.1 200 OK HTTP/1.1 200 OK < access-control-allow-credentials: true access-control-allow-credentials: true < access-control-allow-origin: * access-control-allow-origin: * < content-type: application/json; encoding=utf-8 content-type: application/json; encoding=utf-8 < content-length: 3 content-length: 3 < x-envoy-upstream-service-time: 0 x-envoy-upstream-service-time: 0 < my-response: hello my-response: hello < server: envoy server: envoy
-
Optional: Remove the resources that you created.
kubectl delete httproute httpbin-headers -n httpbin
kubectl delete httproute httpbin-headers -n httpbin kubectl delete TrafficPolicy httpbin-headers -n kgateway-system
Set response headers
Setting headers is similar to adding headers. If the response does not include the header, it is added by the ResponseHeaderModifier
filter. However, if the request already contains the header, its value is overwritten with the value from the ResponseHeaderModifier
filter.
-
Set up a header modifier that sets a
my-response: custom
response header. Choose between the HTTPRoute for a Gateway API-native way, or TrafficPolicy for more flexible attachment options such as a gateway-level policy.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-headers namespace: httpbin spec: parentRefs: - name: http namespace: kgateway-system hostnames: - headers.example rules: - filters: - type: ResponseHeaderModifier responseHeaderModifier: set: - name: my-response value: custom backendRefs: - name: httpbin port: 8000 EOF
Setting Description spec.parentRefs
The name and namespace of the gateway that serves this HTTPRoute. In this example, you use the http
Gateway that was created as part of the get started guide.spec.rules.filters.type
The type of filter that you want to apply to incoming requests. In this example, the ResponseHeaderModifier
filter is used.spec.rules.filters.responseHeaderModifier.set
The name and value of the response header that you want to set. spec.rules.backendRefs
The backend destination you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide. Note: The steps in this section use the Envoy-based kgateway proxy. The steps do not work with the agentgateway proxy.
-
Create an HTTPRoute resource for the route that you want to modify. Note that the example selects the http Gateway that you created before you began.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-headers namespace: httpbin spec: parentRefs: - name: http namespace: kgateway-system hostnames: - headers.example rules: - backendRefs: - name: httpbin port: 8000 EOF
-
Create a TrafficPolicy that sets the
my-response
header to acustom
value on a response. The following example attaches the TrafficPolicy to the http Gateway.kubectl apply -f- <<EOF apiVersion: gateway.kgateway.dev/v1alpha1 kind: TrafficPolicy metadata: name: httpbin-headers namespace: kgateway-system spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: http headerModifiers: response: set: - name: my-response value: custom EOF
-
-
Send a request to the httpbin app on the
headers.example
domain. Verify that you get back a 200 HTTP response code and that themy-response: custom
header was set.curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers -H "host: headers.example:8080"
curl -vi localhost:8080/response-headers -H "host: headers.example"
Example output:
1 2 3 4 5 6 7 8 9 10 11 12 13
... * Request completely sent off < HTTP/1.1 200 OK HTTP/1.1 200 OK < access-control-allow-credentials: true access-control-allow-credentials: true < access-control-allow-origin: * access-control-allow-origin: * ... < my-response: custom my-response: custom < server: envoy server: envoy
-
Optional: Remove the resources that you created.
kubectl delete httproute httpbin-headers -n httpbin
kubectl delete httproute httpbin-headers -n httpbin kubectl delete TrafficPolicy httpbin-headers -n kgateway-system
Remove response headers
You can remove HTTP headers from a response before the response is sent back to the client.
-
Send a request to the httpbin app and find the
content-length
header.curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers -H "host: www.example.com:8080"
curl -vi localhost:8080/response-headers -H "host: www.example.com"
Example output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
... * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK HTTP/1.1 200 OK < access-control-allow-credentials: true access-control-allow-credentials: true < access-control-allow-origin: * access-control-allow-origin: * < content-type: application/json; encoding=utf-8 content-type: application/json; encoding=utf-8 < content-length: 3 content-length: 3 < x-envoy-upstream-service-time: 0 x-envoy-upstream-service-time: 0 < server: envoy server: envoy
-
Set up a header modifier that removes the
content-length
header from the response. Choose between the HTTPRoute for a Gateway API-native way, or TrafficPolicy for more flexible attachment options such as a gateway-level policy.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-headers namespace: httpbin spec: parentRefs: - name: http namespace: kgateway-system hostnames: - headers.example rules: - filters: - type: ResponseHeaderModifier responseHeaderModifier: remove: - content-length backendRefs: - name: httpbin port: 8000 EOF
Setting Description spec.parentRefs
The name and namespace of the gateway that serves this HTTPRoute. In this example, you use the http
gateway that was created as part of the get started guide.spec.rules.filters.type
The type of filter that you want to apply. In this example, the ResponseHeaderModifier
filter is used.spec.rules.filters.responseHeaderModifier.remove
The name of the response header that you want to remove. spec.rules.backendRefs
The backend destination you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide. Note: The steps in this section use the Envoy-based kgateway proxy. The steps do not work with the agentgateway proxy.
-
Create an HTTPRoute resource for the route that you want to modify. Note that the example selects the http Gateway that you created before you began.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-headers namespace: httpbin spec: parentRefs: - name: http namespace: kgateway-system hostnames: - headers.example rules: - backendRefs: - name: httpbin port: 8000 EOF
-
Create a TrafficPolicy that removes the
content-length
header from a response. The following example attaches the TrafficPolicy to the http Gateway.kubectl apply -f- <<EOF apiVersion: gateway.kgateway.dev/v1alpha1 kind: TrafficPolicy metadata: name: httpbin-headers namespace: kgateway-system spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: http headerModifiers: response: remove: - content-length EOF
-
-
Send a request to the httpbin app on the
headers.example
domain . Verify that thecontent-length
response header is removed.curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers -H "host: headers.example:8080"
curl -vi localhost:8080/response-headers -H "host: headers.example"
Example output:
* Mark bundle as not supporting multiuse < HTTP/1.1 200 OK HTTP/1.1 200 OK < access-control-allow-credentials: true access-control-allow-credentials: true < access-control-allow-origin: * access-control-allow-origin: * < content-type: application/json; encoding=utf-8 content-type: application/json; encoding=utf-8 < x-envoy-upstream-service-time: 0 x-envoy-upstream-service-time: 0 < server: envoy server: envoy < transfer-encoding: chunked transfer-encoding: chunked
-
Optional: Remove the resources that you created.
kubectl delete httproute httpbin-headers -n httpbin
kubectl delete httproute httpbin-headers -n httpbin kubectl delete TrafficPolicy httpbin-headers -n kgateway-system
Dynamic response headers
You can return dynamic information about the response in the response header. For more information, see the Envoy docs for Custom request/response headers.
Keep in mind that some variables are available only at certain times. For example, response codes (%RESPONSE_CODE%
) are only available after the response has been sent to the client. If you set a response code in a request header, the value is empty.
You might use some of the following common values in your request or response headers.
Request and response information:
- %REQ(:METHOD)% - HTTP method
- %REQ(:PATH)% - Request path
- %REQ(:AUTHORITY)% - Host header
- %REQ(HEADER_NAME)% - Any request header
- %RESP(HEADER_NAME)% - Any response header
- %RESPONSE_CODE% - HTTP response code
- %RESPONSE_FLAGS% - Response flags
Connection information:
- %DOWNSTREAM_REMOTE_ADDRESS% - Client IP address with port
- %DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT% - Client IP address without port
- %DOWNSTREAM_LOCAL_ADDRESS% - Local address
- %DOWNSTREAM_CONNECTION_ID% - Connection ID
Timing information:
- %START_TIME% - Request start time
- %DURATION% - Request duration
Upstream information:
- %UPSTREAM_HOST% - Upstream host
- %UPSTREAM_CLUSTER% - Upstream Envoy cluster
- %UPSTREAM_LOCAL_ADDRESS% - Upstream local address
Data transfer:
- %BYTES_RECEIVED% - Bytes received
- %BYTES_SENT% - Bytes sent
For more potential values, see Command operators in the Envoy docs.
-
Set up a header modifier that sets the
X-Response-Code
header with the value of the HTTP response code. Choose between the HTTPRoute for a Gateway API-native way, or TrafficPolicy for more flexible attachment options such as a gateway-level policy.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-headers namespace: httpbin spec: parentRefs: - name: http namespace: kgateway-system hostnames: - headers.example rules: - filters: - type: ResponseHeaderModifier responseHeaderModifier: set: - name: x-response-code value: "%RESPONSE_CODE%" backendRefs: - name: httpbin port: 8000 EOF
Setting Description spec.parentRefs
The name and namespace of the gateway that serves this HTTPRoute. In this example, you use the http
Gateway that was created as part of the get started guide.spec.rules.filters.type
The type of filter that you want to apply to responses. In this example, the ResponseHeaderModifier
filter is used.spec.rules.filters.responseHeaderModifier.set
The response header that you want to set. In this example, the x-response-code
header is set to the HTTP response code. For more potential values, see Command operators in the Envoy docs.spec.rules.backendRefs
The backend destination you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide. -
Create an HTTPRoute resource for the route that you want to modify. Note that the example selects the http Gateway that you created before you began.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-headers namespace: httpbin spec: parentRefs: - name: http namespace: kgateway-system hostnames: - headers.example rules: - backendRefs: - name: httpbin port: 8000 EOF
-
Create a TrafficPolicy that sets the
x-response-code
header to the HTTP response code. For more potential values, see Command operators in the Envoy docs. The following example attaches the TrafficPolicy to the http Gateway.kubectl apply -f- <<EOF apiVersion: gateway.kgateway.dev/v1alpha1 kind: TrafficPolicy metadata: name: httpbin-headers namespace: kgateway-system spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: http headerModifiers: response: set: - name: x-response-code value: "%RESPONSE_CODE%" EOF
-
-
Send a request to the httpbin app on the
headers.example
domain. Verify that thex-response-code
response header is set to the HTTP response code.curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: headers.example:8080"
curl -vi localhost:8080/headers -H "host: headers.example"
Example output:
HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * content-type: application/json; encoding=utf-8 date: Tue, 23 Sep 2025 20:05:29 GMT content-length: 479 x-envoy-upstream-service-time: 0 x-response-code: 200 server: envoy
-
Optional: Clean up the resources that you created.
kubectl delete httproute httpbin-headers -n httpbin
kubectl delete httproute httpbin-headers -n httpbin kubectl delete TrafficPolicy httpbin-headers -n kgateway-system