The built-in vcl_recv subroutine is executed when a client request is received by Fastly or as a result of a restart.

Typically, the recv state is used for tasks such as:

The default return path from vcl_recv for GET requests is lookup, which will trigger the vcl_hash subroutine, perform a cache key calculation and look up the resulting address in the cache, ultimately triggering the vcl_hit, vcl_miss or vcl_pass subroutines as appropriate. It's also possible to return(pass), which will still perform a cache key calculation, but will always transition from vcl_hash to vcl_pass. Returning upgrade will terminate the VCL execution and Fastly will maintain the connection as a persistent WebSockets tunnel.

Changes made to the req object in vcl_recv will affect the calculation of the cache key, if the changed properties are included in obj.hash by vcl_hash.

The exception statements restart and error may both be used in recv.

Method specific behavior

At the end of vcl_recv, the default behavior is dependent on the method of the inbound request:

  • GET, HEAD, and PURGE requests will trigger a lookup, while all other methods will cause a pass. This behavior is in the boilerplate VCL and is overridable by using custom VCL in your service.
  • If the return state is lookup, methods other than GET and POST will be converted to GET on the backend request (bereq) and any request body will be dropped. This behavior is part of the Fastly platform and is not overridable.

HINT: With the default boilerplate VCL, the rules above will result in the conversion of a HEAD request into a GET to your origin server, allowing Fastly to populate the resource into our cache, but the response to the client will correctly exclude the content body, since the client requested only the HEAD.

State transitions

  • Inbound request
  • restart
  • return(lookup)hash
  • return(pass)hash
  • errorhash
  • restartrecv
  • return(upgrade)

To see this subroutine in the context of the full VCL flow, see using VCL.


The code example Use microservices to divide up a domain is a good example of the vcl_recv subroutine in use:

Tokens available in this subroutine

The following limited-scope VCL functions and variables are available for use in this subroutine (those in bold are available only in this subroutine, those available in *all* subroutines are not listed):