300 Multiple Choices

When more than one representation exists for a requested resource, the server responds with 300 Multiple Choices. The client is responsible for selecting the option best fitting its requirements.

The response is cacheable by default. To override this behavior, include appropriate Cache-Control headers.

Usage

300 Multiple Choices exists for reactive negotiation: the server hands the client a list of available representations, and the client picks the one fitting its needs, the counterpart to the proactive Content-Negotiation the Accept family drives. The 300 response invites the client to redirect its request to one of the listed identifiers.

When the 300 Multiple Choices status code is received, the message body contents differ depending on the request method. A HEAD request includes no message body. For other methods, the body contains a list from which the client selects the most appropriate response.

For non-HEAD responses, the body contains the list of available choices. The specification mentions the Link header with rel="alternate" as a possible way to list the options, while noting deployment never took hold. If a default response exists or the server has a preferred choice, the Location header identifies this preference.

Example

The client requests a resource and the server offers multiple options. The headers include paths to each resource. Because this follows a GET request, the body provides a clickable list of options.

Request

GET /tech-news HTTP/1.1
Host: www.example.re

Response

HTTP/1.1 300 Multiple Choices
Link: </leading/news.html>; rel="alternate"
Link: </bleeding/news.html>; rel="alternate"
Location: /leading/news.html
Content-Type: text/html
Content-Length: 154

<h2>Choose from one of the following</h2>
<ul>
  <li><a href=/leading/news.html>Leading edge</a>
  <li><a href=/bleeding/news.html>Bleeding edge</a>
</ul>

Why 300 stayed rare

The specification never defines a format for the list of choices. HTTP stays deliberately orthogonal to the content it carries, so a client wanting to select automatically has no standard structure to parse, and automatic selection is exactly what would have made 300 useful. Each server invents a body format, each client would need to understand each format, and the loop never closed.

The history reinforces the point. Early proposals defined dedicated URI and Alternates header fields for carrying the list, and both were dropped for lack of deployment and disagreement over syntax. The Link header with rel="alternate" remains the closest available convention, with the specification itself calling the deployment situation a chicken-and-egg problem.

Code references

.NET

HttpStatusCode.MultipleChoices

Rust

http::StatusCode::MULTIPLE_CHOICES

Rails

:multiple_choices

Go

http.StatusMultipleChoices

Symfony

Response::HTTP_MULTIPLE_CHOICES

Python3.5+

http.HTTPStatus.MULTIPLE_CHOICES

Java

java.net.HttpURLConnection.HTTP_MULT_CHOICE

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_MULTIPLE_CHOICES

Angular

@angular/common/http/HttpStatusCode.MultipleChoices

See also

Last updated: August 18, 2026