Define custom headers

Media CDN lets you specify custom request and response headers.

Custom headers let you do the following:

  • Return geographic data about the client, such as country, region, or city, that you can use to show localized content.
  • Determine whether a response was served from cache (in full or in part) and which cache location it was served from.
  • Remove, replace, or append to both request and response headers.

You can also use headers to route requests to different origins. If you need to configure Cross-Origin Resource Sharing (CORS) headers, configure a CORS policy for each route.

Set custom headers

Headers are set on each route, which lets you add and remove headers for different content, such as manifests or video segments.

By default, added header values are comma-separated and appended to the response or request headers with the same field names.

To overwrite existing values, set replace to true.

The following .routing.pathMatchers[].routeRules[].headerAction example shows headers added and removed in an EdgeCacheService resource:

gcloud edge-cache services describe prod-media-service
  - priority: 1
    description: "video routes"
      - prefixMatch: "/video/"
        # Return the country (or region) associated with the client's IP address.
        - headerName: "client-geo"
          headerValue: "{client_region}"
          replace: true
        # Inform the upstream origin server the request is from Media CDN
        - headerName: "x-downstream-cdn"
          headerValue: "Media CDN"
        - headerName: "X-User-ID"
        - headerName: "X-Other-Internal-Header"

This example does the following:

  • Adds a custom client-geo header to the response by using the {client_region} variable, which returns the country (or region) associated with the client's IP address.
  • Adds a custom x-downstream-cdn header to the request by using a static string.
  • Removes two internal headers.

Dynamic header variables

Custom headers can contain one or more dynamic variables.

Request headers that are a part of cache key policy (cacheKeyPolicy.includedHeaderNames) can contain one or more custom variables. Request headers that contain other dynamic variables can't be a part of the cache key.

Variable Description Supported for request headers Supported for request headers in a cache key Supported for response headers
cdn_cache_status A comma-separated list of the locations (IATA code of the nearest airport) and statuses of each cache node in the request/response path, where the rightmost value represents the cache closest to the user.
client_city The name of the city from which the request originated—for example, Mountain View for Mountain View, California. There is no canonical list of valid values for this variable. The city names can contain US-ASCII letters, numbers, spaces, and the following characters: !#$%&'*+-.^_`|~.
client_city_lat_long The latitude and longitude of the city from which the request originated—for example, 37.386051,-122.083851 for a request from Mountain View.
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_region_subdivision The subdivision—for example, the province or state—of the country associated with the client's IP address. This is a Unicode CLDR subdivision ID, such as USCA or CAON. These Unicode codes are derived from the subdivisions defined by the ISO-3166-2 standard.
client_rtt_msec The estimated round-trip transmission time between the CDN and the HTTP(S) client, in milliseconds. This is the smoothed round-trip time (SRTT) parameter measured by the CDN's TCP stack, per RFC 2988.
device_request_type The type of device that the client is using. These are the valid values: DESKTOP, MOBILE, TABLET, SMART_TV, GAME_CONSOLE, WEARABLE, and UNDETERMINED.
original_request_id The unique identifier assigned to the request that originally generated this response. Populated only if this is different than request_id for cached responses.
origin_name The EdgeCacheOrigin resource from which the response was proxied.
origin_request_header Reflects the value of the Origin header in the request for Cross-Origin Resource Sharing (CORS) use cases.
proxy_status A list of intermediary HTTP proxies in the response path. The value is defined by RFC 9209. An EdgeCacheService resource is represented by Google-Edge-Cache. If the response was fetched from the origin, an EdgeCacheOrigin resource is represented by Google-Edge-Cache-Origin.
tls_sni_hostname The 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 any trailing dot is removed.
tls_version The TLS version negotiated between the client and the load balancer during the SSL handshake. Possible values include TLSv1, TLSv1.1, TLSv1.2, and TLSv1.3. If the client connects by using QUIC instead of TLS, the value is QUIC.
tls_cipher_suite The cipher suite negotiated during the TLS handshake. The value is defined by the IANA TLS Cipher Suite Registry—for example, TLS_RSA_WITH_AES_128_GCM_SHA256. This value is empty for QUIC and unencrypted client connections.

The following considerations apply to custom variables:

  • Existing request and response headers are preserved, except for the following, which are removed:

    • X-User-IP
    • Any headers with X-Google or X-GFE
  • Header keys and values must be compliant with RFC 7230, with obsolete forms disallowed.

  • All header keys are lowercased (per HTTP/2).

  • Some headers are coalesced. When there are multiple instances of the same header key (for example, Via), the load balancer combines their values into a single comma-separated list for a single header key. Only the headers whose values can be represented as a comma-separated list are coalesced. Other headers, such as Set-Cookie, are never coalesced.

  • Some headers are added, or values are appended to them. Media CDN always adds or modifies certain headers, such as Via and X-Forwarded-For.

  • Media CDN expands any response header with a supported variable, even if set by the client or origin. This lets you set dynamic headers from your client (such as a video player) or origin infrastructure, in addition to configuring custom headers. Media CDN doesn't expand variables on the request path.

  • As an example, as per the rules described earlier, X-Goog- and X-Amz- headers are preserved and lowercased.

Cache status values

The {cdn_cache_status} header variable can return multiple values corresponding to the tier of cache that served the response. Consider the following guidelines for interpreting the {cdn_cache_status} header variable:

  • If the header contains hit, the requested content was retrieved from the cache.
  • If the header contains miss, the requested content was not found in a cache node and had to be retrieved from an upstream node.
  • If the header contains fetch, the requested content was retrieved from the origin.
  • If the header contains uncacheable, the requested content was considered uncacheable by some or all components of the caching infrastructure.

    • If the header also contains hit or miss, the requested content was considered uncacheable by some caching components and cacheable by others.
    • If the header does not also contain hit or miss, the requested content was considered uncacheable by all caching components, and all requests for this content are fetched from the origin. To ensure that your content is cached appropriately, review the Media CDN origin requirements.

Default headers

Media CDN adds the following request and response headers to origin requests and client responses, respectively.

Header Description Request Response
x-request-id A unique identifier for the given request. This value is also added to the request log as jsonPayload.requestId, which lets you correlate a client request/response to a log entry.

Returns the age of the cached object (number of seconds it has been in the cache). The age is typically calculated based on when the object was initially cached in a long-tail (shield) cache location.

Responses without an age header are not served from cache.


Identifies Google as the intermediate proxy.

This is set as 1.1 google and cannot be changed.

server Is set as Google-Edge-Cache.

Identifies loops—for example, where the origin host is the same as the user-facing (edge) host.

A token of google is appended to the header as per RFC 8586. The token cannot be changed.


The structured version of the x-forwarded-for header. The forwarded header is defined in RFC 7239.

These headers allow you to identify the IP address of the connecting client when a proxy (or proxies) are in the path. For example, if a client with IP address connects to Media CDN over HTTPS, the forwarded header is populated as follows:

forwarded: [for=;proto=https]

In the case of multiple client-side proxies, the client that connected to Media CDN is the last address appended in the header value.


The unstructured and de-facto standard version of the forwarded header. Values are typically comma-separated.

Both headers are sent in a request to support legacy origins that might not be aware of the forwarded header.

Header keys are lowercased for both request and response headers because header keys are case-insensitive.

Other headers, including the edge point of presence (PoP) location and cache status (such as hit and miss), can be added by using dynamic header variables.