Ana içeriğe geç

Guides / http-status-codes

300 Multiple Choices: the code you will almost never see

300 Multiple Choices means the requested resource has more than one representation and the server is asking the client to choose one instead of picking for it. It is defined by the HTTP standard but almost never used, so if you are looking it up you have probably met a 301 or a 302 rather than a real 300.

What the code was designed for

HTTP supports content negotiation: the same URL can have several representations that differ by format, language or encoding. Normally the server decides, using the client's Accept, Accept-Language and Accept-Encoding headers, and returns the chosen one with a 200. That is server-driven negotiation, and it is what the web does.

300 Multiple Choices covers the other approach, agent-driven negotiation. Instead of choosing, the server answers with a list of the available representations and lets the client or the user pick. The response may include a Location header naming the server's preferred option, which a client is free to follow.

Why you almost never see one

The standard never specified a machine-readable format for the list of choices. Without an agreed format there is nothing for a browser to parse, so no mainstream browser implements a chooser UI for a 300. Browsers usually display the response body as an ordinary page instead, or follow the Location header if one is present, which makes the 300 behave like a weak redirect. Application frameworks and CDNs do not emit it in their default configurations, and server-driven negotiation solves the same problem invisibly and better, so nobody has a reason to switch.

A 300 still turns up in a few places:

  • Apache's mod_negotiation with MultiViews enabled, when several files match a request such as /logo and the module cannot rank them. It generates an HTML list of candidates.
  • Hand-written APIs that deliberately return a JSON list of alternative resource URLs, using 300 as a semantic hint rather than expecting any client to handle it natively.
  • Test suites and protocol conformance tools that exercise every defined status code.

Why people search for 300 status code

Most searches for "300 status code" are not about a 300 at all. The number is the start of the redirect family, so people who saw a redirect in a browser tool, a log or an SEO crawler and remembered "a 3-hundred-something" look up 300 first. What they usually have is:

  • A 301, a permanent redirect, reported by an SEO crawler as part of a chain.
  • A 302, a temporary redirect, the default many frameworks emit.
  • A 304, which is a cache validation response rather than a redirect at all.
  • A crawler summary that groups everything under a "3xx" heading, which then gets read as "300".

If you are trying to work out which redirect a URL returns, the 301 vs 302 guide is the one you want.

How to check whether you really have a 300

  1. Ask for the headers without following any redirect and read the exact number:
    curl -sI https://example.com/some-path | grep -Ei "^(HTTP|location|link|alternates)"
    A genuine 300 shows HTTP/1.1 300 Multiple Choices. Anything else is a different code and a different guide.
  2. If it really is a 300 and you did not intend it, look at Apache first. Disabling MultiViews for that directory, or giving the file an explicit extension in the URL, removes the ambiguity that triggers the negotiation.
  3. If you want the server to choose, keep server-driven negotiation: return 200 with the selected representation and a Vary header naming the request headers you negotiated on, so caches store the variants separately.
  4. If you want to send clients elsewhere, use a real redirect. Permanent moves get 301 or 308, temporary ones get 302 or 307. Do not use 300 as a redirect, because clients are not required to follow it.
  5. Fix the ambiguity at the source. A 300 nearly always means two files or two routes are competing for the same URL, and the durable fix is to make the URL unambiguous.

Spotting an unexpected 300 after a deploy

An unexpected 300 tends to arrive with a server upgrade or a config change, and nobody notices: the page may still look roughly right in a browser while crawlers and API clients get an answer they cannot use. An external check that records the exact status code for each URL surfaces the change on the first run after the deploy. HostTracker has been monitoring websites since 2004 and runs checks from 300+ checkpoints in 158 cities. Check what a URL returns right now with the HTTP check tool, or read the full 3xx redirection family guide.

Check it now

Run the free check against your own site - no account needed.

HTTP check

Monitor this permanently

Get alerted the moment it breaks: HostTracker checks from 300+ locations and notifies you by email, SMS, Slack, Telegram and more.

HostTracker features