Identify backend in response headers


#1

I’m trying to troubleshoot some issues, and it would help me to know which backend (origin) server provided a response (i.e. by inspection of HTTP response headers).

I searched high and low in the Fastly docs, and eventually tried to set this response header:
resp.http.X-Origin = beresp.backend.name

However, I get a validation error:

Variable beresp.backend.name not accessible in method vcl_deliver

Any hints about which variables are within scope for vcl_deliver that can provide info. about which backend responded? Or is this only possible to set on the backend itself (so that provides the header, rather than inserting it retrospectively)?

I could also really use a nice reference for what variables are available (and their scope) in general, if anyone has any nice guides / links that summarise it?


#2

Hi Damien,

I was running into the same problem! Not all VCL variables are available in all VCL subroutines.

Any hints about which variables are within scope for vcl_deliver that can provide info. about which backend responded? Or is this only possible to set on the backend itself (so that provides the header, rather than inserting it retrospectively)?

Fastly provides three values that allow you to see and track origin information:

  • beresp.backend.name => The name of the backend that was used for this request
  • beresp.backend.port => The port of the backend that was used for this request
  • beresp.backend.ip => The IP of the backend that was used for this request

The problem is that all these VCL variables are only available in vcl_fetch. That’s the reason why you received an error because you have tried to reference beresp.backend.name directly in vcl_deliver.

The solution is to define your custom header in vcl_fetch:

sub vcl_fetch {

  ...

  set beresp.http.X-Origin-Name = beresp.backend.name;

  ...

}

You have three possibilities to configure your custom header in vcl_fetch:

  1. Header
  2. VCL Snippet
  3. Custom VCL

The output of beresp.backend.name has the following format:

< X-Origin-Name: <the_fastly_service_id--F_<the_vcl_backend_name>

The values captured in a header within vcl_fetch will flow to vcl_deliver. For example, there will exist a resp.http.X-Origin-Name header in vcl_deliver that corresponds to beresp.backend.name in vcl_fetch. By default, the response header will be included in the response output. You can wrap the set expressions in an if statement to control the behavior.

For security purposes, I recommend adding the custom header to your logging string and removing it from the response headers. You can reference your custom header in your logging string by wrapping it in %{<header_name>}o i.e. %{http.X-Origin-Name}o. Please use the unset statement in vcl_deliver if you want to strip the header from the response:

sub vcl_deliver {

  ...

  unset resp.http.X-Origin-Name;

  ...

}

You can strip your custom header in vcl_deliver via Header, VCL Snippet, or Custom VCL.

Fastly provides great documentation on this topic. Please review their docs on how to track your origin’s name, IP, and port for further information especially if you are shielding.

I could also really use a nice reference for what variables are available (and their scope) in general if anyone has any nice guides/links that summarise it?

The only reference about Fastly VCL variables I know of is the Fastly’s VCL Extensions documentation. However, these docs don’t explain if a variable is read-only and/or read-write and in what VCL subroutines the variable can be used.