The built-in vcl_error subroutine is executed when explicitly triggered by an error statement in vcl_recv, vcl_hit, vcl_miss, vcl_pass, or vcl_fetch, or automatically by Fastly under the following situations:

  • a semantically invalid response or timeout is encountered when Fastly attempts to make a request to a backend server
  • Fastly is unable to negotiate a connection to the backend that is acceptable to both parties (often due to incompatible TLS configurations or expired certificates)
  • the backend has reached its maximum configured number of concurrent connections
  • the backend is unhealthy

Receiving a response from a backend that has an 'error' response status, such as a 500 Internal Server Error will not trigger the vcl_error subroutine, since a 500 response status is syntactically valid. In this case Fastly will simply treat this as a normal response object and will run vcl_fetch.

Typically, triggering an error explicitly using the error statement is a way to signal that you want to return a synthetic response, instead of one from cache or a backend server.

Triggering error in vcl_recv will pass control to vcl_hash and then to vcl_error, while all other subroutines in which error is a valid return state will invoke vcl_error immediately. This is because the vcl_error subroutine operates on a cache object, albeit a synthetic one created by Fastly, and that object is created after the hash state.

Within this subroutine, the obj.status and obj.response variables provide information about the nature of the error. Errors generated by Fastly have a 503 status code and can be differentiated based on the obj.response text.

HINT: When triggering errors from other parts of your VCL, we recommend using a status code in the 6xx range. Numbers lower than 600 are reserved by HTTP standards and those above 700 are used by Fastly for internal signaling.

The synthetic and synthetic.base64 functions can be used to create a response body to send back to the client. This subroutine is the only place in VCL where a response body can be constructed.


Since an error may be triggered at multiple stages of the VCL lifecycle, it is possible for the vcl_error subroutine to be invoked on either of the delivery node or the fetch node, for requests where clustering is enabled.

State transitions


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


The code example Replace origin errors with 'safe' responses is a good example of the vcl_error 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):