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
- A type-map pointing at another negotiable resource — an Apache
.varfile lists a variant whose URI is itself under negotiation, so selecting it starts negotiation over again. - MultiViews overlap — with
Options +MultiViews, the file Apache chooses as the winning variant also matches the negotiation rules (for example, a.varmap and a MultiViews candidate share a base name), so the winner is itself negotiable. - 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 anAlternatesheader 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
.vartype-map file, or the directory withOptions +MultiViews. - Make every variant point to a concrete representation (an actual
page.en.htmlfile), never to another URL that is itself negotiated. - If a
.varmap 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.