vcl_error
The built-in vcl_error
subroutine is executed when explicitly triggered by an error
statement (or return(error)
) 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.
IMPORTANT: If there is an active response object (such as resp
or beresp
) at the moment an error is triggered, it will be lost. When vcl_error
begins, a new response object (obj
) is created, which will become resp
when vcl_error
transitions to vcl_deliver
.
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.
Synthetic responses
The synthetic
and synthetic.base64
statements can be used in vcl_error
to create a response body to send back to the client. vcl_error
is the only place in VCL where a response body can be constructed. To learn more about constructing responses at the edge in vcl_error
, see the error
statement.
Clustering
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
vcl_error |
To see this subroutine in the context of the full VCL flow, see using VCL.
Example
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, those available in *all* subroutines are not listed):
- client.socket.congestion_algorithm
- client.socket.cwnd
- client.socket.nexthop
- client.socket.pace
- client.socket.ploss
- client.socket.tcp_info
- client.socket.tcpi_advmss
- client.socket.tcpi_bytes_acked
- client.socket.tcpi_bytes_received
- client.socket.tcpi_data_segs_in
- client.socket.tcpi_data_segs_out
- client.socket.tcpi_delivery_rate
- client.socket.tcpi_delta_retrans
- client.socket.tcpi_last_data_sent
- client.socket.tcpi_max_pacing_rate
- client.socket.tcpi_min_rtt
- client.socket.tcpi_notsent_bytes
- client.socket.tcpi_pacing_rate
- client.socket.tcpi_pmtu
- client.socket.tcpi_rcv_mss
- client.socket.tcpi_rcv_rtt
- client.socket.tcpi_rcv_space
- client.socket.tcpi_rcv_ssthresh
- client.socket.tcpi_reordering
- client.socket.tcpi_rtt
- client.socket.tcpi_rttvar
- client.socket.tcpi_segs_in
- client.socket.tcpi_segs_out
- client.socket.tcpi_snd_cwnd
- client.socket.tcpi_snd_mss
- client.socket.tcpi_snd_ssthresh
- client.socket.tcpi_total_retrans
- esi.allow_inside_cdata
- obj.age
- obj.entered
- obj.grace
- obj.headers
- obj.http.{NAME}
- obj.is_pci
- obj.lastuse
- obj.proto
- obj.response
- obj.stale_if_error
- obj.stale_while_revalidate
- obj.status
- obj.ttl
- req.backend.ip
- req.backend.name
- req.backend.port
- req.digest.ratio
- req.esi
- req.hash
- waf.blocked
- waf.executed
- waf.failures
- waf.logged
- waf.passed