# HTTP 300 Multiple Choices — Status Code Meaning & Examples

> The resource has several representations and the client should pick one.

300 is the rarely used 'there are options' redirect. The server lists alternatives — different formats or languages — and may suggest a preferred one in the `Location` header. Content negotiation through Accept headers replaced it in practice, so mainstream servers almost never send it.

- Class: 3xx Redirection
- Retry: Not applicable
- Cacheable by default: yes
- Defined in: [RFC 9110 §15.4.1 — 300 Multiple Choices](https://www.rfc-editor.org/rfc/rfc9110.html#section-15.4.1)

## Example response

```http
HTTP/1.1 300 Multiple Choices
Location: /docs/en
```

## When you'll see it

- Servers with agent-driven content negotiation enabled.
- Hand-built APIs that list alternative representations.

## How to use it well

1. Prefer server-driven negotiation (`Accept`, `Accept-Language`) and a direct 200.
2. If you do use 300, include a `Location` for the preferred choice so browsers can follow it automatically.

## Send a 300 from your server

### Express

```
res.redirect(300, "/docs/en");
```

### Next.js route handler

```
return NextResponse.redirect(new URL("/docs/en", request.url), 300);
```

### Flask

```
return redirect("/docs/en", code=300)
```

### Go net/http

```
http.Redirect(w, r, "/docs/en", http.StatusMultipleChoices)
```

### nginx

```
return 300 /docs/en;
```

## FAQ

### Do browsers follow a 300 automatically?

Only when a Location header is present. Otherwise they show the response body, which should list the choices as links.

## Related status codes

- [301 Moved Permanently](https://www.devkult.com/http/301.md)
- [302 Found](https://www.devkult.com/http/302.md)
- [406 Not Acceptable](https://www.devkult.com/http/406.md)

Open the interactive page: https://www.devkult.com/http/300