Problem

A request comes back 506 Variant Also Negotiates, and it’s one of the rarest status codes you’ll ever see in the wild. It’s defined in RFC 2295, the experimental transparent content negotiation spec, and it means exactly one thing: the server tried to pick the best version of a resource, and the version it picked was also configured to be negotiated — a loop the server can’t resolve. So instead of an infinite regress, it gives up and returns 506.

Content negotiation is the mechanism where one URL can serve several representations — page.html and page.fr.html and page.de.html, chosen by the client’s Accept-Language. Normally the server picks one concrete file and sends it. A 506 says the “best” file it selected isn’t a concrete file at all; it’s another negotiable resource, and now the server is chasing its own tail.

Top 3 Causes

  1. A type-map pointing at another negotiable resource — an Apache .var file lists a variant whose URI is itself under negotiation, so selecting it starts negotiation over again.
  2. MultiViews overlap — with Options +MultiViews, the file Apache chooses as the winning variant also matches the negotiation rules (for example, a .var map and a MultiViews candidate share a base name), so the winner is itself negotiable.
  3. A negotiated variant listed as its own alternative — a variant list that, directly or through a symlink/alias, includes the negotiating URL among its choices.

Diagnosis with DechoNet

  • HTTP Check — Confirm the endpoint really returns 506 and inspect the response headers. Content negotiation leaves fingerprints: look for Vary, TCN (Transparent Content Negotiation), and an Alternates header listing variants. Those tell you negotiation is active on the URL and give you the variant names to trace back in the server config.

Resolution Checklist

  • Locate the resource in your server config — the .var type-map file, or the directory with Options +MultiViews.
  • Make every variant point to a concrete representation (an actual page.en.html file), never to another URL that is itself negotiated.
  • If a .var map and MultiViews both cover the same base name, disable one — running both over the same files is the classic way to create the loop.
  • Remove any entry in a variant list that resolves back to the negotiating URL itself, including via aliases or symlinks.
  • Re-request the URL and confirm it now returns 200 with a single chosen variant.

Check your own domain now

Free, no sign-up. Runs the exact check this guide describes and shows what to fix.