티스토리 수익 글 보기
HyperText Transfer Protocol
Internet-Draft
Intended status: Standards Track , Ed.
Expires: March 4, 2027 Google LLC
August 31, 2026
The No-Vary-Search HTTP Caching Extension
draft-ietf-httpbis-no-vary-search-latest
Abstract
This specification defines an extension to HTTP Caching, changing how
the URI query component impacts caching. It introduces the “”No-
Vary-Search”” response header field, which allows origin servers to
signal to caches that certain parts of the query component do not
semantically affect the served response and can be ignored for cache
matching purposes.
About This Document
This note is to be removed before publishing as an RFC.
The latest revision of this draft can be found at
. Status information for this document may be found at
.
Discussion of this document takes place on the HTTP Working Group
mailing list (), which is archived at
. Working Group
information can be found at .
Source for this draft and an issue tracker can be found at
.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Expires March 4, 2027 [Page 1]
Internet-Draft No-Vary-Search August 2026
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as “work in progress.”
This Internet-Draft will expire on March 4, 2027.
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust’s Legal
Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Conventions and Definitions . . . . . . . . . . . . . . . . . 4
3. HTTP header field definition . . . . . . . . . . . . . . . . 5
4. Data model . . . . . . . . . . . . . . . . . . . . . . . . . 6
5. Parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5.1. Parse a URL variation config . . . . . . . . . . . . . . 6
5.2. Obtain a URL variation config . . . . . . . . . . . . . . 9
5.2.1. Examples . . . . . . . . . . . . . . . . . . . . . . 10
5.3. Parse a key . . . . . . . . . . . . . . . . . . . . . . . 12
5.3.1. Examples . . . . . . . . . . . . . . . . . . . . . . 12
6. Comparing . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6.1. Examples . . . . . . . . . . . . . . . . . . . . . . . . 16
7. Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
8. Security Considerations . . . . . . . . . . . . . . . . . . . 20
9. Privacy Considerations . . . . . . . . . . . . . . . . . . . 21
10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 21
10.1. HTTP Field Names . . . . . . . . . . . . . . . . . . . . 21
10.2. No-Vary-Search Dictionary Keys Registry . . . . . . . . 21
11. References . . . . . . . . . . . . . . . . . . . . . . . . . 22
11.1. Normative References . . . . . . . . . . . . . . . . . . 22
11.2. Informative References . . . . . . . . . . . . . . . . . 23
11.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 25
Expires March 4, 2027 [Page 2]
Internet-Draft No-Vary-Search August 2026
Authors’ Addresses . . . . . . . . . . . . . . . . . . . . . . . 26
1. Introduction
HTTP caching [HTTP-CACHING] is based on reusing resources which match
across a number of cache keys, with the most important one being the
presented target URI (Section 7.1 of [HTTP]). However, sometimes
multiple URIs can represent the same resource. This leads to caches
not always being as helpful as they could be: if the cache contains a
response under one URI, but the response is then requested under
another, the cached version will be ignored.
The “No-Vary-Search” response header field defines a caching
extension, as described in Section 4 of [HTTP-CACHING], that tackles
a specific subset of this general problem, for when different URIs
that differ only in their query component identify the same resource.
It allows resources to declare that some or all parts of the query
component do not semantically affect the served response, and thus
can be ignored for cache matching purposes. This is achieved by
interpreting the query component as a sequence of parameters encoded
using the “application/x-www-form-urlencoded” format [WHATWG-URL].
For example, if the order of the parameters within the query
component does not affect which resource is identified, this is
indicated using
No-Vary-Search: key-order
If specific query parameters (e.g., ones indicating something for
analytics) do not semantically affect the served resource, this is
indicated using
No-Vary-Search: params=(“utm_source” “utm_medium” “utm_campaign”)
And if the resource instead wants to take an allowlist-based
approach, where only certain known query parameters semantically
affect the served response, they can use
No-Vary-Search: except=(“productId”)
Note that “cache busting”, the practice of changing a part of the
query component to create a distinct cache key and force retrieval of
a newer response, can be made ineffective by the “”No-Vary-Search””
response header field.
Section 3 defines the new “”No-Vary-Search”” response header field,
using the [STRUCTURED-FIELDS] framework. Section 4 and Section 5
illustrate the data model for how the field value can be represented
in specifications, and the process for parsing the raw output from
Expires March 4, 2027 [Page 3]
Internet-Draft No-Vary-Search August 2026
the structured field parser into that data model. Section 6 gives
the key algorithm for comparing if two URLs are equivalent under the
influence of the header field; notably, it leans on the decomposition
of the query component into keys and values given by the application/
x-www-form-urlencoded [1] format specified in [WHATWG-URL]. (As
such, this header field is not useful for URLs whose query component
does not follow that format.) Finally, Section 7 explains how to
extend Section 4 of [HTTP-CACHING] to take this new equivalence into
account.
From a deployment perspective, this extension is implemented by HTTP
caches, including browser caches, content delivery networks, and
forward proxies. Origin servers send the “”No-Vary-Search”” response
header field to provide instructions to these caches. Caches that
implement this extension use these instructions to determine when a
previously stored response can be safely reused for a new request,
even if the query components of the target URIs differ.
2. Conventions and Definitions
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and
“OPTIONAL” in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
In this document, the terms “URI” and “URL” are used interchangeably,
depending on context. “URI” is used in the context of [URI], [HTTP],
and [HTTP-CACHING], whereas “URL” is used in the context of the
algorithms specified in [WHATWG-URL].
The term “query parameters” in this document refers to the keys and
values resulting from parsing a URL’s query component using the
application/x-www-form-urlencoded [2] format [WHATWG-URL].
This document also adopts some conventions and notation typical in
WHATWG and W3C usage, especially as it relates to algorithms. See
[WHATWG-INFRA], and in particular:
o its definition of lists, including the list literal notation << 1,
2, 3 >>.
o its definition of strings, including their representation as code
units.
Expires March 4, 2027 [Page 4]
Internet-Draft No-Vary-Search August 2026
(Other concepts used are called out using inline references.)
3. HTTP header field definition
The “”No-Vary-Search”” response header field is a structured field
[STRUCTURED-FIELDS] whose value MUST be a dictionary (Section 3.2 of
[STRUCTURED-FIELDS]).
It has the following constraints:
o If present, the “key-order” entry’s value MUST be a boolean
(Section 3.3.6 of [STRUCTURED-FIELDS]).
o If present, the “params” entry’s value MUST be an inner list of
strings (Section 3.1.1 of [STRUCTURED-FIELDS]).
o If present, the “except” entry’s value MUST be an inner list of
strings (Section 3.1.1 of [STRUCTURED-FIELDS]).
o The “except” entry MUST NOT be present if the “params” entry is
also present.
The dictionary MAY contain entries whose keys are not one of “key-
order”, “params”, and “except”, but their meaning is not defined by
this specification. Implementations of this specification will
ignore such entries (but future documents might assign meaning to
such entries). Future extensions to this dictionary MUST NOT
restrict the set of URIs that are considered equivalent; they can
only expand it. If a future extension requires restricting
equivalence, it MUST be deployed as a new HTTP header field to ensure
safety.
The “”No-Vary-Search”” response header field is set by origin
servers. Intermediaries MUST NOT insert, delete, or modify the
field’s value unless they are acting as the origin server for that
response.
A parsing algorithm is defined in Section 5.2.
Expires March 4, 2027 [Page 5]
Internet-Draft No-Vary-Search August 2026
4. Data model
A _URL variation config_ consists of the following:
no-vary params
either the special value *wildcard* or a list of strings
vary params
either the special value *wildcard* or a list of strings
vary on key order
a boolean
The default URL variation config is a URL variation config whose no-
vary params is an empty list, vary params is *wildcard*, and vary on
key order is true.
The obtain a URL variation config algorithm (Section 5.2) ensures
that all URL variation configs obey the following constraints:
o vary params is a list if and only if the no-vary params is
*wildcard*; and
o no-vary params is a list if and only if the vary params is
*wildcard*.
5. Parsing
5.1. Parse a URL variation config
To parse a URL variation config given _value_:
1. If _value_ is null, then return the default URL variation config.
2. Let _result_ be a new URL variation config.
3. Set _result_’s vary on key order to true.
Expires March 4, 2027 [Page 6]
Internet-Draft No-Vary-Search August 2026
4. If _value_[“”key-order””] exists:
1. Let _keyOrderValue_ be the “item_or_inner_list” component of
the tuple _value_[“”key-order””] (ignoring any parameters).
2. If _keyOrderValue_ is not a boolean, then return the default
URL variation config.
3. Set _result_’s vary on key order to the boolean negation of
_keyOrderValue_.
5. If both _value_[“”params””] and _value_[“”except””] exist, then
return the default URL variation config.
6. If neither _value_[“”params””] nor _value_[“”except””] exists:
1. Set _result_’s no-vary params to an empty list.
2. Set _result_’s vary params to *wildcard*.
7. If _value_[“”params””] exists:
1. Let _paramsValue_ be the “item_or_inner_list” component of
the tuple _value_[“”params””] (ignoring any parameters).
Expires March 4, 2027 [Page 7]
Internet-Draft No-Vary-Search August 2026
2. If _paramsValue_ is not an inner list, then return the
default URL variation config.
3. Let _paramsList_ be a list containing the “bare_item”
component of each tuple in _paramsValue_ (ignoring any
parameters).
4. If any item in _paramsList_ is not a string, then return the
default URL variation config.
5. Set _result_’s no-vary params to the result of applying parse
a key (Section 5.3) to each item in _paramsList_.
6. Set _result_’s vary params to *wildcard*.
8. Otherwise, if _value_[“”except””] exists:
1. Let _exceptValue_ be the “item_or_inner_list” component of
the tuple _value_[“”except””] (ignoring any parameters).
2. If _exceptValue_ is not an inner list, then return the
default URL variation config.
3. Let _exceptList_ be a list containing the “bare_item”
component of each tuple in _exceptValue_ (ignoring any
parameters).
Expires March 4, 2027 [Page 8]
Internet-Draft No-Vary-Search August 2026
4. If any item in _exceptList_ is not a string, then return the
default URL variation config.
5. Set _result_’s vary params to the result of applying parse a
key (Section 5.3) to each item in _exceptList_.
6. Set _result_’s no-vary params to *wildcard*.
9. Return _result_.
In general, this algorithm is strict and tends to return the
default URL variation config whenever it sees something it doesn’t
recognize. This is because the default URL variation config
behavior will just cause fewer cache hits, which is an acceptable
fallback behavior.
The input to this algorithm is generally obtained by parsing a
structured field (Section 4.2 of [STRUCTURED-FIELDS]) using
field_type “dictionary”.
5.2. Obtain a URL variation config
To obtain a URL variation config given an HTTP response (Section 3.4
of [HTTP]) _response_:
1. Let _fieldValue_ be the result of parsing the “”No-Vary-Search””
response header field from _response_ as a Dictionary
(Section 4.2 of [STRUCTURED-FIELDS]). If parsing fails or the
field is absent, let _fieldValue_ be null.
2. Return the result of parsing a URL variation config (Section 5.1)
given _fieldValue_.
Expires March 4, 2027 [Page 9]
Internet-Draft No-Vary-Search August 2026
5.2.1. Examples
The following illustrates how various inputs are parsed, in terms of
their impact on the resulting no-vary params and vary params:
+——————–+———————————————-+
| Input | Result |
+——————–+———————————————-+
| “No-Vary-Search: | no-vary params: (empty list) vary params: |
| key-order” | *wildcard* vary on key order: false |
| | |
| “No-Vary-Search: | no-vary params: << ""a"" >> vary params: |
| params=(“a”)” | *wildcard* |
| | |
| “No-Vary-Search: | no-vary params: *wildcard* vary params: << |
| except=("x")" | ""x"" >> |
| | |
| “No-Vary-Search: | no-vary params: (empty list) vary params: |
| params=()” | *wildcard* |
| | |
| “No-Vary-Search: | no-vary params: *wildcard* vary params: |
| except=()” | (empty list) |
+——————–+———————————————-+
The following inputs are all invalid and will cause the default URL
variation config to be returned:
Expires March 4, 2027 [Page 10]
Internet-Draft No-Vary-Search August 2026
+——————————–+———————————-+
| Input | Explanation |
+——————————–+———————————-+
| “No-Vary-Search: key- | “key-order” expects a boolean, |
| order=”not a boolean”” | not a string |
| | |
| “No-Vary-Search: params=”not | “params” expects an inner list, |
| an inner list”” | not a string |
| | |
| “No-Vary-Search: params=(not- | “params” items must be strings |
| a-string)” | (tokens are invalid) |
| | |
| “No-Vary-Search: params=?0” | “params” expects an inner list, |
| | not a boolean |
| | |
| “No-Vary-Search: params=?1” | “params” expects an inner list, |
| | not a boolean |
| | |
| “No-Vary-Search: params=?1, | “params” and “except” cannot |
| except=(“x”)” | both be present |
| | |
| “No-Vary-Search: params=(“a”), | “params” and “except” cannot |
| except=(“x”)” | both be present |
| | |
| “No-Vary-Search: params=(), | “params” and “except” cannot |
| except=()” | both be present |
| | |
| “No-Vary-Search: except=”not | “except” expects an inner list, |
| an inner list”” | not a string |
| | |
| “No-Vary-Search: except=(not- | “except” items must be strings |
| a-string)” | (tokens are invalid) |
| | |
| “No-Vary-Search: except=?1” | “except” expects an inner list, |
| | not a boolean |
+——————————–+———————————-+
The following inputs are valid, but somewhat unconventional. They
are shown alongside their more conventional form.
Expires March 4, 2027 [Page 11]
Internet-Draft No-Vary-Search August 2026
+——————————–+———————————-+
| Input | Conventional form |
+——————————–+———————————-+
| “No-Vary-Search: key-order=?1” | “No-Vary-Search: key-order” |
| | |
| “No-Vary-Search: | “No-Vary-Search: key-order, |
| except=(“x”)”, key-order | except=(“x”)” |
| | |
| “No-Vary-Search: params=()” | (omit the header field) |
| | |
| “No-Vary-Search: key-order=?0” | (omit the header field) |
+——————————–+———————————-+
5.3. Parse a key
To parse a key given an ASCII string _keyString_:
1. Let _keyBytes_ be the isomorphic encoding [3] [WHATWG-INFRA] of
_keyString_.
2. Replace any 0x2B (+) in _keyBytes_ with 0x20 (SP).
3. Let _keyBytesDecoded_ be the percent-decoding [4] [WHATWG-URL] of
_keyBytes_.
4. Let _keyStringDecoded_ be the UTF-8 decoding without BOM [5]
[WHATWG-ENCODING] of _keyBytesDecoded_.
5. Return _keyStringDecoded_.
5.3.1. Examples
The parse a key algorithm allows encoding non-ASCII key strings in
the ASCII structured header field format, similar to how the
application/x-www-form-urlencoded [6] format [WHATWG-URL] allows
encoding an entire entry list of keys and values in a URI (which is
restricted to ASCII characters). For example:
Expires March 4, 2027 [Page 12]
Internet-Draft No-Vary-Search August 2026
No-Vary-Search: params=(“%C3%A9+%E6%B0%97”)
Notice that while the input string “”%C3%A9+%E6%B0%97″” consists
entirely of ASCII characters (as required at the HTTP layer), the
percent-decoding step used by the cache produces a non-ASCII result.
This will result in a URL variation config whose no-vary params are
<< ""e 気"" >>. Note that the “”+”” character in the encoded
string is mapped to a space (SP). As explained in a later example,
the canonicalization process during equivalence testing means this
will treat as equivalent URIs such as:
o “https://example.com/?e 気=1”
o “https://example.com/?e+気=2”
o “https://example.com/?%C3%A9%20気=3”
o “https://example.com/?%C3%A9+%E6%B0%97=4”
and so on, since they all are parsed [7] [WHATWG-URL] to having the
same key “”e 気””.
6. Comparing
Two URLs [8] [WHATWG-URL] _urlA_ and _urlB_ are _equivalent modulo
variation config_ given a URL variation config _variationConfig_ if
the following algorithm returns true:
1. If the scheme, host, port, or path of _urlA_ and _urlB_ differ,
then return false.
2. If _variationConfig_ is equivalent to the default URL variation
config, then:
1. If _urlA_’s query equals _urlB_’s query, then return true.
Expires March 4, 2027 [Page 13]
Internet-Draft No-Vary-Search August 2026
2. Return false.
In this case, even URL pairs that might appear the same after
running the application/x-www-form-urlencoded parser [9]
[WHATWG-URL] on their queries, such as “https://example.com/a”
and “https://example.com/a?”, or “https://example.com/
foo?a=b&&&c” and “https://example.com/foo?a=b&c=”, will be
treated as inequivalent.
3. Let _searchParamsA_ and _searchParamsB_ be empty lists.
4. If _urlA_’s query is not null, then set _searchParamsA_ to the
result of running the application/x-www-form-urlencoded parser
[10] [WHATWG-URL] given the isomorphic encoding [11]
[WHATWG-INFRA] of _urlA_’s query.
5. If _urlB_’s query is not null, then set _searchParamsB_ to the
result of running the application/x-www-form-urlencoded parser
[12] [WHATWG-URL] given the isomorphic encoding [13]
[WHATWG-INFRA] of _urlB_’s query.
6. If _variationConfig_’s no-vary params is a list, then:
1. Set _searchParamsA_ to a list containing those items _pair_
in _searchParamsA_ where _variationConfig_’s no-vary params
does not contain _pair_[0].
2. Set _searchParamsB_ to a list containing those items _pair_
in _searchParamsB_ where _variationConfig_’s no-vary params
does not contain _pair_[0].
Expires March 4, 2027 [Page 14]
Internet-Draft No-Vary-Search August 2026
7. Otherwise, if _variationConfig_’s vary params is a list, then:
1. Set _searchParamsA_ to a list containing those items _pair_
in _searchParamsA_ where _variationConfig_’s vary params
contains _pair_[0].
2. Set _searchParamsB_ to a list containing those items _pair_
in _searchParamsB_ where _variationConfig_’s vary params
contains _pair_[0].
8. If _variationConfig_’s vary on key order is false, then:
1. Let _keyLessThan_ be an algorithm taking as inputs two pairs
(_keyA_, _valueA_) and (_keyB_, _valueB_), which returns
whether _keyA_ is code unit less than [14] [WHATWG-INFRA]
_keyB_.
2. Set _searchParamsA_ to the result of sorting [15]
[WHATWG-INFRA] _searchParamsA_ in ascending order with
_keyLessThan_.
3. Set _searchParamsB_ to the result of sorting [16]
[WHATWG-INFRA] _searchParamsB_ in ascending order with
_keyLessThan_.
9. If _searchParamsA_’s size is not equal to _searchParamsB_’s
size, then return false.
Expires March 4, 2027 [Page 15]
Internet-Draft No-Vary-Search August 2026
10. Let _i_ be 0.
11. While _i_ < _searchParamsA_'s size:
1. If _searchParamsA_[_i_][0] does not equal
_searchParamsB_[_i_][0], then return false.
2. If _searchParamsA_[_i_][1] does not equal
_searchParamsB_[_i_][1], then return false.
3. Set _i_ to _i_ + 1.
12. Return true.
6.1. Examples
Due to how the application/x-www-form-urlencoded parser canonicalizes
query strings, there are some cases where query strings which do not
appear obviously equivalent, will end up being treated as equivalent
after parsing.
So, for example, given any non-default value for the ""No-Vary-
Search"" response header field, such as "No-Vary-Search: key-order",
we will have the following equivalences:
Expires March 4, 2027 [Page 16]
Internet-Draft No-Vary-Search August 2026
+------------+----------------+-------------------------------------+
| First | Second Query | Explanation |
| Query | | |
+------------+----------------+-------------------------------------+
| null | "?" | A null query is parsed the same as |
| | | an empty string |
| | | |
| "?a=x" | "?%61=%78" | Parsing performs percent-decoding |
| | | |
| "?a=e" | "?a=%C3%A9" | Parsing performs percent-decoding |
| | | |
| "?a=%f6" | "?a=%ef%bf%bd" | An invalid UTF-8 sequence and the |
| | | literal U+FFFD character are both |
| | | parsed as U+FFFD (�) |
| | | |
| "?a=x&&&&" | "?a=x" | Parsing splits on "&" and discards |
| | | empty strings |
| | | |
| "?a=" | "?a" | Both parse as having an empty |
| | | string value for "a" |
| | | |
| "?a=%20" | "?a= &" | "%20" is parsed as U+0020 SPACE |
| | | |
| "?a=+" | "?a= &" | "+" is parsed as U+0020 SPACE |
+------------+----------------+-------------------------------------+
Note that no Unicode normalization is performed during this
comparison. For example, a query string of "?a=%C3%A9" (using the
NFC encoding of "e") and "?a=e%CC%81" (using the NFD encoding of
"é") will not be treated as equivalent.
7. Caching
To reuse a stored response, Section 4 of [HTTP-CACHING] requires that
the presented target URI and that of the stored response match. If a
cache implements the "No-Vary-Search" extension, this matching
requirement is also satisfied if the URIs are equivalent modulo URL
variation config (Section 6) given the stored response's "No-Vary-
Search" header.
This document does not alter the requirements for cache invalidation
(see Section 4.4 of [HTTP-CACHING]). A cache MAY invalidate stored
responses for URIs that are equivalent modulo URL variation config,
but is not required to do so. Therefore, state-changing requests
might not invalidate all conceptually equivalent responses.
Expires March 4, 2027 [Page 17]
Internet-Draft No-Vary-Search August 2026
Note that the ""No-Vary-Search"" response header field operates in
addition to content negotiation and the "Vary" header field (see
Section 4.1 of [HTTP-CACHING]).
Cache implementations MAY fail to reuse a stored response whose
target URI matches _only_ modulo URL variation config, if the cache
has a stored response with a more recent "Date" header field which:
o has a target URI which is equal to the presented target URI,
excluding the query, and
o has a non-empty value for the ""No-Vary-Search"" response header
field, and
o has a ""No-Vary-Search"" response header field value different
from the stored response being considered for reuse.
When a cache has multiple stored responses with conflicting ""No-
Vary-Search"" values, preferring the response with the most recent
"Date" header field helps ensure caches converge on the origin's
latest caching policy.
Caches aren't required to reuse stored responses, generally.
However, the above expressly empowers caches to, if it is
advantageous for performance or other reasons, search a smaller
number of stored responses.
That is, because caches might store more than one response for a
given target URI path and authority, they need a way to
efficiently look up the ""No-Vary-Search"" response header field
value without accessing all cached responses. Such a cache might
take steps like the following to identify a stored response in a
performant way, before checking the other conditions in Section 4
of [HTTP-CACHING]:
1. Let exactMatch be cache[presentedTargetURI]. If it is a
stored response that can be reused, return it.
Expires March 4, 2027 [Page 18]
Internet-Draft No-Vary-Search August 2026
2. Let targetPath be presentedTargetURI, with query parameters
removed.
3. Let lastNVS be mostRecentNVS[targetPath]. If it does not
exist, return null.
4. Let simplifiedURL be the result of simplifying
presentedTargetURI according to lastNVS (by removing query
parameters which are not significant, and sorting [17]
[WHATWG-INFRA] parameters in ascending order by key, if key
order is to be ignored).
5. Let nvsMatch be cache[simplifiedURL]. If it does not exist,
return null. (It is assumed that this was written when
storing in the cache, in addition to the exact URL.)
6. Let variationConfig be obtained (Section 5.2) from nvsMatch.
7. If nvsMatch's target URI and presentedTargetURI are not
equivalent modulo URL variation config (Section 6) given
variationConfig, then return null.
8. If nvsMatch is a stored response that can be reused, return
it. Otherwise, return null.
To aid cache implementation efficiency, servers SHOULD NOT send
different non-empty values for the ""No-Vary-Search"" response header
field in response to requests for a given target URI path and
authority over time, unless there is a need to update how they handle
the query component. Doing so would cause cache implementations that
use a strategy like the above to miss some stored responses that
could otherwise have been reused.
Expires March 4, 2027 [Page 19]
Internet-Draft No-Vary-Search August 2026
8. Security Considerations
The main risk to be aware of is a cache returning a response that was
originally fetched from a URL different from the one requested. In a
web browser, this could cause the user to see a response fetched from
a URL different from the one displayed when they hovered a link, or
the URL displayed in the URL bar.
For shared caches, such as CDNs or forward proxies, returning a
response for a different URL carries the risk of cross-user state
leakage. If a server incorrectly declares that a query parameter
does not affect the response, but that parameter actually dictates
user-specific or sensitive content, the shared cache might serve one
user's personalized response to another user. However, because the
origin strictly controls the ""No-Vary-Search"" response header
field, it is the origin's responsibility to ensure that ignored
parameters are safe to disregard for all users.
The ""No-Vary-Search"" response header field alters the algorithm
that caches use for URI identifier comparison. As discussed in
[RFC6943], altering identifier comparison logic can lead to security
issues, primarily through "false positives" where two identifiers are
incorrectly deemed equivalent.
Because URL query parsing replaces invalid percent-encoded UTF-8
sequences with "U+FFFD", lossy decoding can map distinct query
strings onto the same cache key (for example, "?a=%f6" and
"?a=%ef%bf%bd"). Origins should not rely on invalid percent-encoded
sequences being distinguishable, as this is a concrete example of the
false positives warned about in [RFC6943].
Incorrect configuration of this field can exacerbate cache poisoning
or data leakage risks by causing such false positives. Origin
servers MUST NOT declare a parameter as no-vary if doing so would
bypass server processing required for safe response reuse. This
includes parameters used for authorization, user identification,
signature verification, user consent, routing, auditing, revocation,
or any other security-sensitive operations.
However, since the impact is limited to query parameters, this does
not cross the relevant security boundary, which is the origin
([ORIGIN]). (See also the host [18] from the perspective of web
browser security UI [19] [WHATWG-URL]). Indeed, origins already have
complete control over how they present URLs and response bodies,
including on the client side via technology such as
history.replaceState() [20] [HTML] or service workers.
Expires March 4, 2027 [Page 20]
Internet-Draft No-Vary-Search August 2026
9. Privacy Considerations
This proposal is adjacent to the highly-privacy-relevant space of
navigational tracking [21], which often uses query parameters to pass
along user identifiers. If an origin were to encode user identifiers
in its URI, this proposal can reduce user tracking by private caches,
since preventing server processing of such user IDs bypasses the
server in favor of the cache. It does not interfere with existing
navigational tracking mitigations [22], or any known future ones
being contemplated. [NAV-TRACKING-MITIGATIONS]
However, this tracking reduction does not fully apply to shared
caches (such as content delivery networks and forward proxies), which
still receive the requests containing the identifiers. Furthermore,
an errant configuration that incorrectly ignores parameters related
to user identity or private state could expose cached content meant
for one user to another. While this mistake can occur with standard
caching, the ""No-Vary-Search"" response header field increases the
surface area for such misconfigurations, making it critical that
origins accurately classify their query parameters.
10. IANA Considerations
10.1. HTTP Field Names
IANA is requested to enter the following into the Hypertext Transfer
Protocol (HTTP) Field Name Registry
(https://www.iana.org/assignments/http-fields/http-fields.xhtml
[23]):
Field Name: "No-Vary-Search"
Status: permanent
Structured Type: Dictionary
Reference: this document
Comments: (none)
10.2. No-Vary-Search Dictionary Keys Registry
IANA is requested to create a new registry, "No-Vary-Search
Dictionary Keys", at https://www.iana.org/assignments/http-fields/
[24].
The registration policy is "IETF Review" (see Section 4.8 of
[RFC8126]).
Expires March 4, 2027 [Page 21]
Internet-Draft No-Vary-Search August 2026
A registration request MUST include the following fields:
o Key: the dictionary key for the ""No-Vary-Search"" response header
field
o Description: a brief description of the key's purpose
o Reference: a pointer to the specification that defines the key
The initial contents of this registry are:
+-------------+----------------------------------------+------------+
| Key | Description | Reference |
+-------------+----------------------------------------+------------+
| "key-order" | Indicates if query parameter order | this |
| | affects caching | document |
| | | |
| "params" | A list of query parameters that do not | this |
| | affect caching | document |
| | | |
| "except" | A list of query parameters that affect | this |
| | caching | document |
+-------------+----------------------------------------+------------+
11. References
11.1. Normative References
[HTTP] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "HTTP Semantics", STD 97, RFC 9110,
DOI 10.17487/RFC9110, June 2022,
.
[HTTP-CACHING]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., “HTTP Caching”, STD 98, RFC 9111,
DOI 10.17487/RFC9111, June 2022,
.
Expires March 4, 2027 [Page 22]
Internet-Draft No-Vary-Search August 2026
[RFC2119] Bradner, S., “Key words for use in RFCs to Indicate
Requirement Levels”, BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
.
[RFC8174] Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, .
[STRUCTURED-FIELDS]
Nottingham, M. and P. Kamp, “Structured Field Values for
HTTP”, RFC 9651, DOI 10.17487/RFC9651, September 2024,
.
[URI] Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform
Resource Identifier (URI): Generic Syntax”, STD 66,
RFC 3986, DOI 10.17487/RFC3986, January 2005,
.
[WHATWG-ENCODING]
van Kesteren, A., “Encoding Living Standard”, May 2026,
.
WHATWG
[WHATWG-INFRA]
van Kesteren, A. and D. Denicola, “Infra Living Standard”,
July 2026, .
WHATWG
[WHATWG-URL]
van Kesteren, A., “URL Living Standard”, July 2026,
.
WHATWG
11.2. Informative References
[HTML] van Kesteren, A., “HTML Living Standard”, August 2026,
.
WHATWG
[NAV-TRACKING-MITIGATIONS]
Snyder, P. and J. Yasskin, “Navigational-Tracking
Mitigations”, n.d.,
.
Expires March 4, 2027 [Page 23]
Internet-Draft No-Vary-Search August 2026
W3C Privacy CG
[ORIGIN] Barth, A., “The Web Origin Concept”, RFC 6454,
DOI 10.17487/RFC6454, December 2011,
.
[RFC6943] Thaler, D., Ed., “Issues in Identifier Comparison for
Security Purposes”, RFC 6943, DOI 10.17487/RFC6943, May
2013, .
[RFC8126] Cotton, M., Leiba, B., and T. Narten, “Guidelines for
Writing an IANA Considerations Section in RFCs”, BCP 26,
RFC 8126, DOI 10.17487/RFC8126, June 2017,
.
11.3. URIs
[1] https://url.spec.whatwg.org/#concept-urlencoded
[2] https://url.spec.whatwg.org/#concept-urlencoded
[3] https://infra.spec.whatwg.org/#isomorphic-encode
[4] https://url.spec.whatwg.org/#percent-decode
[5] https://encoding.spec.whatwg.org/#utf-8-decode-without-bom
[6] https://url.spec.whatwg.org/#concept-urlencoded
[7] https://url.spec.whatwg.org/#concept-urlencoded-parser
[8] https://url.spec.whatwg.org/#concept-url
[9] https://url.spec.whatwg.org/#concept-urlencoded-parser
[10] https://url.spec.whatwg.org/#concept-urlencoded-parser
[11] https://infra.spec.whatwg.org/#isomorphic-encode
[12] https://url.spec.whatwg.org/#concept-urlencoded-parser
[13] https://infra.spec.whatwg.org/#isomorphic-encode
[14] https://infra.spec.whatwg.org/#code-unit-less-than
[15] https://infra.spec.whatwg.org/#list-sort-in-ascending-order
[16] https://infra.spec.whatwg.org/#list-sort-in-ascending-order
Expires March 4, 2027 [Page 24]
Internet-Draft No-Vary-Search August 2026
[17] https://infra.spec.whatwg.org/#list-sort-in-ascending-order
[18] https://url.spec.whatwg.org/#concept-url-host
[19] https://url.spec.whatwg.org/#url-rendering-simplification
[20] https://html.spec.whatwg.org/multipage/nav-history-
apis.html#dom-history-replacestate
[21] https://privacycg.github.io/nav-tracking-
mitigations/#terminology
[22] https://privacycg.github.io/nav-tracking-mitigations/#deployed-
mitigations
[23] https://www.iana.org/assignments/http-fields/http-fields.xhtml
[24] https://www.iana.org/assignments/http-fields/
Index
D
default URL variation config 6-10, 13
E
equivalent modulo variation config 13
O
obtain a URL variation config 6, 9
P
parse a URL variation config 6, 9
parse a key 8-9, 12
Acknowledgments
This document benefited from valuable reviews and suggestions by:
o Adam Rice
o Julian Reschke
o Kevin McNee
Expires March 4, 2027 [Page 25]
Internet-Draft No-Vary-Search August 2026
o Liviu Tinta
o Mark Nottingham
o Martin Thomson
o Valentin Gosu
Authors’ Addresses
Domenic Denicola
Google LLC
Email: d@domenic.me
Jeremy Roman
Google LLC
Email: jbroman@chromium.org
Nidhi Jaju (editor)
Google LLC
Email: nidhijaju@chromium.org
Expires March 4, 2027 [Page 26]