Create custom headers in URL maps

This page describes how custom headers work in URL maps used by regional external HTTP(S) load balancers and internal HTTP(S) load balancers.

Custom request and response headers let you specify additional headers that the load balancer can add to HTTP(S) requests and responses. Depending on the information detected by the load balancer, these headers can include the following information:

  • Latency to the client
  • Geographic location of the client's IP address
  • Parameters of the TLS connection

Before you begin

If necessary, update to the latest version of the Google Cloud CLI:

gcloud components update

How custom headers work

Custom headers work as follows:

  • When the load balancer makes a request to the backend, the load balancer adds request headers.

  • The load balancer sets response headers before returning a response to the client.

To enable custom headers for regional external HTTP(S) load balancers and internal HTTP(S) load balancers, you specify a list of header names and header values in the URL map configuration file.

Header names must have the following properties:

  • The header name must be a valid HTTP header-field name definition per RFC 7230.
  • The header name must not be X-User-IP.
  • The header name must not begin with X-Google, X-Goog-, X-GFE, or X-Amz-.
  • The header name must not be Host or authority. Both Host and authority are special keywords reserved by Google Cloud. You can't modify these headers for Envoy-based load balancers. Instead, we recommend that you create other custom headers (for example, MyHost) so that you don't interfere with the reserved header names.
  • A header name must not appear more than once in the list of headers.

Header names are case-insensitive. When header names are passed to an HTTP/2 backend, the HTTP/2 protocol encodes header names as lowercase.

Header values must have the following properties:

  • The header value must be a valid HTTP header field definition per RFC 7230, with obsolete forms disallowed.
  • The header value cannot be blank. Blank headers are rejected.
  • The header value can include one or more variables, enclosed by curly braces, that expand to values that the load balancer provides. For a complete list of variables allowed in the header value, see Variables that can appear in the header value.

In header values, leading whitespace and trailing whitespace are insignificant and are not passed to the backend. To allow for curly braces in header values, the load balancer interprets two opening curly braces ({{) as a single opening brace ({), and two closing curly braces (}}) as a single closing brace (}).

Add request or response headers

To add request or response headers, use the gcloud CLI to edit the URL map as follows:

gcloud compute url-maps edit URL_MAP_NAME \
    --region=REGION

Following is a sample YAML file that shows you how to use variables in custom headers:

   defaultService: regions/REGION/backendServices/BACKEND_SERVICE_1
   name: regional-lb-map
   region: region/REGION
   hostRules:
   - hosts:
     - '*'
     pathMatcher: matcher1
   pathMatchers:
   - defaultService: regions/REGION/backendServices/BACKEND_SERVICE_1
     name: matcher1
     routeRules:
       - matchRules:
           - prefixMatch: /PREFIX
         priority: PRIORITY # 0 is highest
         routeAction:
           weightedBackendServices:
             - backendService: regions/REGION/backendServices/BACKEND_SERVICE_1
               weight: 100
               headerAction:
                 requestHeadersToAdd:
                 - headerName: X-header-1-client-region
                   headerValue: "{client_region}"
                 - headerName: X-header-2-client-ip-port
                   headerValue: "{client_ip_address}, {client_port}"
                   replace: True
                 requesteHeadersToRemove:
                 - header-3-name
                 responseHeadersToAdd:
                 - headerName: X-header-4-server-ip-port
                   headerValue: "{server_ip_address}, {server_port}"
                   replace: True
                 responseHeadersToRemove:
                 - header-5-name
                 - header-6-name

Note the following behaviors:

  • If a response header with custom variables resolves to an empty string it is removed.
  • If a request header with custom variables resolves to an empty string, it is retained with an empty string placeholder.
  • If a custom request header includes a custom variable, and an incoming client request also includes the same header, the client request header value will be replaced with the new value provided by the load balancer's custom header.

Variables that can appear in the header value

The following variables can appear in custom header values.

Variable Description
client_region The country (or region) associated with the client's IP address. This is a Unicode CLDR region code, such as US or FR. (For most countries, these codes correspond directly to ISO-3166-2 codes.)
client_rtt_msec Estimated round-trip transmission time between the load balancer and the HTTP(S) client, in milliseconds. This is the smoothed round-trip time (SRTT) parameter measured by the load balancer's TCP stack, per RFC 2988. Smoothed RTT is an algorithm that deals with variations and anomalies that may occur in RTT measurements.
client_ip_address The client's IP address. This is the same as the client IP address that is the next-to-last address in the X-Forwarded-For header.
client_port The client's source port.
client_encrypted Set to true if the connection between the client and the load balancer is encrypted (using HTTPS, HTTP/2 or HTTP/3), set to false otherwise.
client_protocol The HTTP protocol used for communication between the client and the load balancer. One of HTTP/1.0, HTTP/1.1, HTTP/2, or HTTP/3.
origin_request_header Reflects the value of the Origin header in the request for Cross-Origin Resource Sharing (CORS) use cases.
server_ip_address The IP address of the load balancer that the client connects to. This can be useful when multiple load balancers share common backends. This is the same as the last IP address in the X-Forwarded-For header.
server_port The destination port number that the client connects to.
tls_sni_hostname Server name indication (as defined in RFC 6066), if provided by the client during the TLS or QUIC handshake. The hostname is converted to lowercase and with any trailing dot removed.
tls_version TLS version negotiated between client and load balancer during the SSL handshake. Possible values include: TLSv1, TLSv1.1, TLSv1.2, and TLSv1.3. If the client connects using QUIC instead of TLS, the value is QUIC.
tls_cipher_suite Cipher suite negotiated during the TLS handshake. The value is four hex digits defined by the IANA TLS Cipher Suite Registry, for example, 009C for TLS_RSA_WITH_AES_128_GCM_SHA256. This value is empty for QUIC and for unencrypted client connections.
tls_ja3_fingerprint JA3 TLS/SSL fingerprint if the client connects using HTTPS, HTTP/2 or HTTP/3.

The load balancer expands variables to empty strings when it cannot determine their values. For example:

  • Geographic location variables when the IP address's location is unknown
  • TLS parameters when TLS is not in use
  • The {origin_request_header} when the request does not include an Origin header

Geographic values are estimates based on the client's IP address. From time to time, Google updates the data that provides these values in order to improve accuracy and to reflect geographic and political changes.

Limitations

The following limitation applies to custom headers used with regional load balancers:

  • You can't configure custom headers on regional backend services used by regional external HTTP(S) load balancers and internal HTTP(S) load balancers.
  • The following custom header variables aren't supported with regional external HTTP(S) load balancers:
    • cdn_cache_id
    • cdn_cache_status
    • client_region_subdivision
    • client_city
    • client_city_lat_long