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: CookieorVary: Authorizationeffectively disables shared caching, since nearly every value differs.Vary: *makes the response uncacheable in practice.- If you choose
Access-Control-Allow-Originper request, you must also sendVary: Origin.
Further reading: HTTP caching explained · CORS errors explained
How to set Vary
res.set("Vary", "Accept-Encoding");module.exports = {
async headers() {
return [
{
source: "/(.*)",
headers: [{ key: "Vary", value: "Accept-Encoding" }],
},
];
},
};add_header Vary "Accept-Encoding" always;
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.