302 Found
When a resource is temporarily available at a different URL, the server responds with 302 Found, previously known as "Moved Temporarily". The client follows the Location header to reach the resource. Because the redirect is temporary, clients keep using the original URI for future requests.
Usage
When the 302 Found status code is received, the client understands the requested resource has temporarily moved. A second request retrieves the resource at the new location. This is simpler than a 301 because the client is not expected to update internal links.
Common triggers for 302 responses include HTTP-to-HTTPS upgrades (often better served by 301), URL normalization (trailing slash), A/B testing, geolocation-based content routing, and temporary maintenance redirects.
302 vs 301
Both codes point a client elsewhere, and the split is whether the original address survives.
302 Found keeps the original address in play. The resource is reachable somewhere else for now, the original stays the canonical location, and search engines keep indexing and ranking the original rather than the target. Responses are not cacheable by default, so removing the redirect takes effect immediately.
301 retires the original. Ranking signals move to the target, the index entry follows, and clients cache the answer by default. A stored 301 keeps sending a browser to the target long after the server stops sending the redirect, which makes a mistaken 301 slow and awkward to reverse.
Choosing 302 for a permanent move is the more common error, and the cost is quiet: the migration appears to work while the new addresses never accumulate the standing of the old ones. Choosing 301 for a temporary detour is louder and harder to undo.
Maintenance windows, geographic routing, A/B tests, and login detours are 302. Domain changes, protocol upgrades, and consolidated duplicate addresses are 301.
302 vs 303
Both codes send the client to a different address without claiming the original has moved permanently. The difference is how explicit each one is about the method.
302 Found leaves the method ambiguous. The HTTP specification expects the original method to repeat, while the Fetch Standard requires browsers to convert a redirected POST into a GET with the body dropped. Browser traffic follows the mandate, and other clients follow the specification or their own history, so a form submission redirected with 302 arrives as a GET from browsers and unpredictably from everything else.
303 states the intent directly. A 303 instructs the client to issue a GET against the address in Location, whatever method the original request used, with HEAD alone staying unchanged. Nothing is left to convention.
The post-redirect-get pattern is where the choice shows. A form handler answering with 303 sends the browser to a result page by GET, so a refresh re-requests the result rather than resubmitting the form. 302 usually produces the same outcome through client behavior rather than through the response, and 307 produces the opposite by preserving the POST.
Example
The client requests a resource temporarily moved. The server indicates the new location and supplies a relevant message for client-side display.
Request
GET /news.html HTTP/1.1
Host: www.example.re
Response
HTTP/1.1 302 Found
Location: http://www.example.re/testing/news.html
Content-Type: text/html
Content-Length: 155
<h1>The Newsfeed has moved</h1>
<body>
The site is under development and the newsfeed has
temporarily moved to
<a href=/testing/news.html>here</a>.
</body>
Code references
.NET
HttpStatusCode.Found
Rust
http::StatusCode::FOUND
Rails
:found
Go
http.StatusFound
Symfony
Response::HTTP_FOUND
Python3.5+
http.HTTPStatus.FOUND
Java
java.net.HttpURLConnection.HTTP_MOVED_TEMP
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_MOVED_TEMPORARILY
Angular
@angular/common/http/HttpStatusCode.Found
See also
- RFC 9110: HTTP Semantics
- WHATWG Fetch Standard: HTTP-redirect fetch
- Google: HTTP status codes and network errors
- 303
- 307
- 301
- Redirects
- HTTP status codes