307 Temporary Redirect
When a resource is temporarily available at a different URL and the original request method must be preserved, the server responds with 307 Temporary Redirect. This status code was introduced in the HTTP/1.1 specification.
Usage
The 307 Temporary Redirect status code indicates the target resource is available at a different URL. The client makes a new request to the URL specified in the Location header and is not permitted to change the request method. This differs from the 302 status code, which allows the client to switch from POST to GET.
When the desired behavior is to change the request method, the 303 status code is the recommended alternative. For example, redirecting a POST form submission to a confirmation page uses 303 with a GET follow-up.
The client must repeat the exact same method, headers, and body to the new URL. The server processes the redirected request normally. Because the 307 Temporary Redirect is not persistent, future requests are expected to use the original URL and revalidate the temporary change.
The permanent counterpart is 308, which preserves the request method identically but signals the move is permanent and clients update stored links.
The response is not cacheable by default. To make the redirect cacheable, add a Cache-Control or Expires header.
The 307 Temporary Redirect status code also serves as an internal redirect when an HSTS policy is declared through the Strict-Transport-Security header or the HSTS preload list. The client uses the status code for redirection from HTTP to a secure connection using HTTPS without contacting the server.
307 vs 302
Both codes redirect without claiming a permanent move, and both leave the original address indexed. The difference is whether the method survives.
307 Temporary Redirect preserves the method and the body. A POST redirected with 307 arrives at the new address as a POST with the payload intact, which the specification requires rather than merely encourages.
302 carries no method guarantee. The Fetch Standard requires browsers to convert a redirected POST into a GET, so a form submission redirected with 302 arrives as an empty GET from every browser.
The choice therefore depends on the traffic. Ordinary page-level redirects serving GET requests behave identically under either code. Anything carrying a request body needs 307 to survive the hop, and 303 covers the opposite intent of deliberately converting the follow-up to GET.
307 vs 303
Both codes redirect temporarily, and the request method is what separates them.
307 Temporary Redirect repeats the original method and body at the new address. A POST stays a POST, which suits a request needing to complete somewhere else unchanged.
303 does the reverse on purpose, converting the follow-up to GET whatever the original method, with HEAD alone staying unchanged. The conversion is the point rather than a side effect, and the pattern where a form handler sends the browser to a result page depends on the conversion.
Choosing between them is a question about the target address. A target expecting the same operation wants 307. A target holding a document to display wants 303.
Example
The client requests a resource and the server responds with 307 Temporary Redirect because the resource is available at an alternate location.
Request
GET /news.html HTTP/1.1
Host: www.example.re
Response
HTTP/1.1 307 Temporary Redirect
Location: http://www.example.re/breaking/news.html
Code references
.NET
HttpStatusCode.TemporaryRedirect
Rust
http::StatusCode::TEMPORARY_REDIRECT
Rails
:temporary_redirect
Go
http.StatusTemporaryRedirect
Symfony
Response::HTTP_TEMPORARY_REDIRECT
Python3.5+
http.HTTPStatus.TEMPORARY_REDIRECT
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_TEMPORARY_REDIRECT
Angular
@angular/common/http/HttpStatusCode.TemporaryRedirect
See also
- RFC 9110: HTTP Semantics
- WHATWG Fetch Standard: HTTP-redirect fetch
- Google: HTTP status codes and network errors
- 302
- 303
- 308
- Cache-Control
- Expires
- Redirects
- HTTP status codes