---
title: vcl_recv
summary: null
url: https://www.fastly.com/documentation/reference/vcl/subroutines/recv
---

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:

- [normalizing](https://fiddle.fastly.dev/fiddle/ecf9fa4a) client input
- routing: [dynamically allocating a backend](https://fiddle.fastly.dev/fiddle/296463fa) to the request
- applying authentication or evaluating access rights (e.g., API keys, paywalls, session tokens, [URL tokens](https://fiddle.fastly.dev/fiddle/a04d81ca))
- triggering synthetic responses for known paths (e.g., to implement [redirects for old URLs](https://www.fastly.com/documentation/solutions/tutorials/redirects/))
- [requiring TLS](https://fiddle.fastly.dev/fiddle/f27c54ad)
- Denying requests based on [geolocation](https://www.fastly.com/documentation/solutions/tutorials/geofence/) or [ACLs](https://fiddle.fastly.dev/fiddle/fafb88af)
- Enabling serve stale behavior
- Setting limits or defaults
- Enabling [Image Optimization](https://www.fastly.com/documentation/guides/full-site-delivery/image-optimization/about-fastly-image-optimizer)
- Validating initial request to remove 'trusted' headers that should only be added by edge logic
- Changing backend after a `restart`, as part of the [pre-flight](https://fiddle.fastly.dev/fiddle/f1bbff1e) pattern, [A/B testing](https://www.fastly.com/documentation/solutions/tutorials/ab-testing/) or [origin failover](https://fiddle.fastly.dev/fiddle/03bb096b).
- Invoking [WebSockets passthrough](https://www.fastly.com/documentation/guides/concepts/real-time-messaging/websockets-tunnel)

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](https://www.fastly.com/documentation/guides/concepts/real-time-messaging/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](https://www.fastly.com/documentation/guides/full-site-delivery/custom-vcl/developer-guide-using/#custom-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.
