Minimal reproduction of a difference in HTTP method handling between Vercel Production and Preview deployments of the same project.
Preview deployments reject HTTP methods outside the standard set with
405 INVALID_REQUEST_METHOD before routing runs. Production deployments forward the
same methods to an external rewrite destination.
The whole project is one static index.html plus a single catch-all rewrite:
{
"rewrites": [
{ "source": "/:path*", "destination": "https://httpbingo.org/anything" }
]
}https://httpbingo.org/anything is a public echo service. It accepts arbitrary HTTP
methods and returns 200 with the method reflected in the JSON body, so any rejection
observed below originates from Vercel and not from the rewrite destination.
Origin control, taken directly against the echo service with no Vercel in the path:
| Method | Status | Body |
|---|---|---|
POST |
200 | "method": "POST" |
QUERY |
200 | "method": "QUERY" |
FOOBAR |
200 | "method": "FOOBAR" |
vercel deploy --yes # first deploy is assigned to Production
vercel deploy --yes # subsequent deploys are PreviewThen, against each deployment URL:
curl -i -X POST https://<deployment>/probe -H 'content-type: application/json' -d '{}'
curl -i -X QUERY https://<deployment>/probe -H 'content-type: application/json' -d '{}'
curl -i -X FOOBAR https://<deployment>/probe -H 'content-type: application/json' -d '{}'Disable Deployment Protection on the project first, otherwise every request is answered
with 401 before the method is looked at.
| Method | Production | Preview |
|---|---|---|
POST |
200, echoed by origin | 200, echoed by origin |
PATCH |
200, echoed | 200, echoed |
DELETE |
200, echoed | 200, echoed |
OPTIONS |
200 | 200 |
QUERY |
200, echoed "method": "QUERY" |
405 INVALID_REQUEST_METHOD |
FOOBAR |
200, echoed "method": "FOOBAR" |
405 INVALID_REQUEST_METHOD |
Production, QUERY — forwarded, origin answered:
HTTP/2 200
server: Vercel
fly-request-id: 01M1E5ZNCDN0HF05FTEHV3020Q-fra
x-vercel-id: lhr1::mnhls-1788256179581-98ceba728789
...
"method": "QUERY",
Preview, QUERY — rejected before routing:
HTTP/2 405
content-type: text/plain; charset=utf-8
server: Vercel
x-vercel-error: INVALID_REQUEST_METHOD
x-vercel-id: lhr1::hkxxb-1788256180288-67dc5c2dde5e
content-length: 83
Method not allowed
INVALID_REQUEST_METHOD
lhr1::hkxxb-1788256180288-67dc5c2dde5e
FOOBAR gives the same results as QUERY on both targets, so this covers every method
outside the standard set rather than QUERY specifically. The Production responses carry
fly-request-id from the echo origin; the Preview 405s carry no origin header at all.
Deployment Protection was disabled when these captures were taken, so the rejection does not come from the preview authentication layer.
Hookdeck receives inbound webhooks sent with arbitrary HTTP methods. Our staging environment is a Preview deployment, so the methods our product is designed to accept are rejected at the edge there but not in production.