301 vs 308 (POST dropped) high
301 redirect drops POST body (use 308)
Clients following a 301/302 often turn POST into GET and drop the body; API and form endpoints need 308 or 307.
What you see
HTTP/1.1 301 Moved Permanently Location: https://api.example.com/v2/orders 400 Bad Request: missing required field
What’s actually happening
A form submission or API call starts failing right after a URL change. The redirect resolves, but the destination gets an empty GET instead of the POST you sent, so it returns 400/422 for missing fields or just silently does nothing. It looks intermittent because GET endpoints survive the redirect fine while POST/PUT/PATCH/DELETE break. curl -L reproduces it: the method flips to GET on the second request.
Common causes
- An API or form endpoint was moved (HTTP to HTTPS, host change, trailing-slash normalization) using a 301 or 302.
- Per RFC, 301/302 allow clients to rewrite the method, and most browsers and many HTTP libraries downgrade POST to GET and discard the body.
- A trailing-slash or www/non-www redirect sits in front of the API and rewrites POSTs before they reach the handler.
- Code assumes redirects are transparent and never inspects the method after a Location bounce.
- A reverse proxy normalizes the path with a default 301 that doesn't preserve the verb.
How to fix it
- Use 308 for permanent, 307 for temporary on any non-GET endpoint308 and 307 are defined to keep the original method and body across the redirect (RFC 7538 / RFC 9110). Swap the 301 to 308 (or 302 to 307) wherever POST/PUT/PATCH/DELETE traffic can land.
- Verify the method survivesRun curl -L -X POST -d '{"x":1}' -H 'Content-Type: application/json' https://api.example.com/old and confirm the final request is still POST with the body intact. With 301 you'll see it become GET.
- Better yet, don't redirect API traffic at allRedirects on hot API paths add a round trip per call. Update clients and SDKs to hit the canonical URL directly, and keep the 308 only as a safety net for stragglers.
- Handle the trailing-slash and host normalization explicitlyIf a framework auto-redirects /orders to /orders/ or non-www to www, make that rule a 308 for API routes, or disable strict-slash redirects on the API router so POSTs pass straight through.
Stop it recurring
Reserve 301/302 for pages a browser GETs; use 308/307 on every endpoint that accepts a request body.
Related errors