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

  1. Follow the Get started guide to install Gloo Gateway.

  2. Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.

  3. Get the external address of the gateway and save it in an environment variable.

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.

  1. Set up a header modifier that adds a my-response: hello response header. Choose between the HTTPRoute for a Gateway API-native way, or GlooTrafficPolicy for more flexible attachment options such as a gateway-level policy.

  2. 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 the my-response header in the response.

    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
    < 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
      
  3. Optional: Remove the resources that you created.

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.

  1. Set up a header modifier that sets a my-response: custom response header. Choose between the HTTPRoute for a Gateway API-native way, or GlooTrafficPolicy for more flexible attachment options such as a gateway-level policy.

  2. Send a request to the httpbin app on the headers.example domain. Verify that you get back a 200 HTTP response code and that the my-response: custom header was set.

    Example output:

      ...
    * 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
      
  3. Optional: Remove the resources that you created.

Remove response headers

You can remove HTTP headers from a response before the response is sent back to the client.

  1. Send a request to the httpbin app and find the content-length header.

    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
    < content-length: 3
    content-length: 3
    < x-envoy-upstream-service-time: 0
    x-envoy-upstream-service-time: 0
    < server: envoy
    server: envoy
      
  2. 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 GlooTrafficPolicy for more flexible attachment options such as a gateway-level policy.

  3. Send a request to the httpbin app on the headers.example domain . Verify that the content-length response header is removed.

    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
      
  4. Optional: Remove the resources that you created.

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.

  1. 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 GlooTrafficPolicy for more flexible attachment options such as a gateway-level policy.

  2. Send a request to the httpbin app on the headers.example domain. Verify that the x-response-code response header is set to the HTTP response code.

    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
      
  3. Optional: Clean up the resources that you created.