Glossary

Content negotiation

Content negotiation is the mechanism by which a server returns different representations of the same URL depending on what the client says it accepts. The client advertises formats, encodings and languages in request headers; the server chooses among what it has. The practical consequence for anyone auditing a site is that the response received depends on the request made — so a single observation describes one client's experience, not the site's behaviour.

What gets negotiated in practice

Compression, which almost every server negotiates and which is the most universally used form of it.

Image format, where a pipeline returns a modern format to clients that accept one and an older format to those that do not.

Language, on sites that serve translations from one URL rather than from separate ones.

Media type, on APIs that can return more than one representation of the same resource.

Why it makes an audit client-dependent

A scan advertising support for modern formats and receiving an older one is seeing either a pipeline that does not negotiate or one with nothing better stored.

Those two produce the same observation and need different fixes, which is why the finding is phrased as what was delivered rather than as what visitors receive.

The same applies to compression: an uncompressed response may mean compression is off, or that an intermediary stripped the negotiation header on the way through.

Which is also why the alternative — declaring the variants in the markup — fails more visibly, and is easier to audit for exactly that reason.

The alternative: declaring variants in the markup

Instead of negotiating in the response, a page can declare the candidates and let the browser choose — a picture element listing formats, a srcset listing widths.

That moves the decision from the server to the client, and it makes the available options visible to anyone reading the HTML.

It costs markup and it removes a class of silent failure, since a missing candidate is visible where a non-negotiating server is not.

Both approaches are legitimate. Most image pipelines use the first; most hand-built pages use the second.

The caching consequence

A negotiated response must declare what it varied on, or a shared cache will serve one client's variant to another.

That is not a subtlety: it is how a client that accepts no modern format receives one and fails to display it.

Compression negotiation without the corresponding declaration is the most common instance, which is why most servers add it automatically.

So negotiation and cache variation are two halves of one mechanism, and implementing the first without the second creates the failure it was meant to avoid.

How a server decides

The client sends preference lists with relative weights, so it expresses an order rather than a single demand.

The server intersects those preferences with what it can produce and picks the best available match.

Where nothing matches, the correct answer is a 406 — which almost no server sends, preferring to return a default instead.

A server that ignores the preferences entirely and always returns one representation is not negotiating, and is indistinguishable from one that has nothing else to offer.

Frequently asked questions

Why does my image audit show an old format when I serve modern ones?
Either the pipeline does not negotiate on what the client accepts, or it has no modern version stored for those files. Checking what a browser receives for the same URL separates them.
Is declaring variants in markup better than negotiating?
It is more visible and easier to audit, at the cost of markup. Negotiation is less work per page and fails more quietly. Both are legitimate.
Do I need Vary when I negotiate?
Yes. Without it a shared cache will serve one client's variant to another, which is precisely the failure negotiation was meant to avoid.

Sources

Related

VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.

Scan a website