devkult_
tools29converters34

Vary

response headercaching

Lists the request headers that change the response, so caches keep a separate copy for each variant.

Caches key stored responses by URL. If a response also depends on a request header — compression, language, the CORS Origin — Vary tells caches to include that header in the key. Without it, a Brotli response can reach a client that can't decode it, or one origin's CORS headers can be served to another.

Syntax

Vary: <header-name>, <header-name>…   or   Vary: *

Defined in RFC 9110 §12.5.5 — Vary.

Examples

Vary: Accept-Encoding

separate compressed and uncompressed copies (servers add this automatically)

Vary: Origin

the CORS headers depend on the calling origin

Vary: Accept-Language

content negotiated by language

Good to know

  • Vary: Cookie or Vary: Authorization effectively disables shared caching, since nearly every value differs.
  • Vary: * makes the response uncacheable in practice.
  • If you choose Access-Control-Allow-Origin per request, you must also send Vary: Origin.

Further reading: HTTP caching explained · CORS errors explained

How to set Vary

Express
res.set("Vary", "Accept-Encoding");
Next.js (next.config.js)
module.exports = {
  async headers() {
    return [
      {
        source: "/(.*)",
        headers: [{ key: "Vary", value: "Accept-Encoding" }],
      },
    ];
  },
};
nginx
add_header Vary "Accept-Encoding" always;
Apache (.htaccess)
Header always set Vary "Accept-Encoding"

Check it

Fetch only the response headers and filter for Vary. In the browser, it's under Response Headers in DevTools → Network.

curl -sI https://example.com/ | grep -i '^vary:'

To compare response headers across many URLs at once, use the HTTP Status Checker.

Frequently asked questions

Why does my CDN return the wrong CORS headers?

It cached a response made for one origin and served it to another. Add Vary: Origin wherever Access-Control-Allow-Origin depends on the request.

Related headers