FreeToGenerate.com

Compare two ETags under both of HTTP's comparison functions, and see which conditional requests a weak tag quietly makes impossible. Nothing is uploaded.

weak · opaque tag 1

weak · opaque tag 1

Include the quotes, and the W/ prefix if there is one. Both are part of the value.

Try one

The two comparison functions

Weak comparison
match
Strong comparison
no match

The two functions disagree on this pair, which is the case worth knowing about: whether these tags are considered equal depends entirely on which request header is doing the asking.

These two tags are identical, and strong comparison still rejects them, because at least one is weak. That is not a quirk: a weak ETag can never satisfy If-Match, so every conditional write against this resource fails no matter what the client sends. If you need optimistic concurrency, the server has to emit a strong tag.

What each conditional header would do

If-None-Match cache revalidation, and the 304 response
the precondition is satisfied
If-Match conditional writes, and optimistic concurrency
the precondition fails
If-Range resuming a partial download
the precondition fails

Also available in: Español · Português · Français · العربية

ETag checker

Compare two entity tags under the weak and strong comparison functions, and see what each conditional request header would do with them.

What an ETag is, and what the W/ means

An ETag is an opaque string a server attaches to a version of a resource. The client stores it, sends it back on the next request, and the server can answer with a 304 instead of the whole body if nothing has changed. The value has a small grammar: an optional W/ prefix, then the tag itself in mandatory double quotes.

The quotes are part of the value rather than decoration, and the permitted characters are narrower than people expect — the set is %x21 and %x23 to %x7E, which excludes both the double quote and, less obviously, the space. A backslash is allowed, though the specification advises against one because older recipients may try to unescape it.

The W/ prefix means the tag is a weak validator. The usual explanation is that a weak tag identifies a semantically equivalent version rather than a byte-identical one, which is true and makes it sound like a minor annotation about precision. It is not. It changes what the tag can be used for.

How to use it

  1. Put the server's ETag in the first box. Exactly as it appears in the response header, quotes and W/ prefix included. Anything malformed is explained rather than silently ignored.
  2. Put the tag being compared against it in the second. Usually that is what a client would send in If-None-Match or If-Match.
  3. Read both comparison results, then the header table. Where the two functions disagree, the answer depends entirely on which header is asking — and the table below spells out what each one would do.

Two comparison functions, and the one nobody mentions

HTTP does not have a comparison function for entity tags. It has two, and it requires different ones in different places. RFC 9110 section 13.1.2 says a recipient must use the weak comparison function for If-None-Match. Section 13.1.1 says an origin server must use the strong comparison function for If-Match.

Weak comparison ignores the W/ prefix entirely and compares the opaque tags. Strong comparison requires the tags to be equal and both to be strong. The consequence is the thing worth carrying away: a weak ETag never satisfies strong comparison, not even against an identical copy of itself. The specification prints this in its own table — W/"1" against W/"1" is a match under weak comparison and no match under strong.

So a weak ETag caches perfectly and cannot be written against. Every conditional PUT or PATCH that uses If-Match for optimistic concurrency fails, permanently, no matter what the client sends. There is no error explaining why; the precondition simply never passes. If your API returns 412 on every update and the ETag starts with W/, that is the reason.

This is not a rare configuration. Sampling the top 250 domains, 173 of which responded, only 20.2% send an ETag at all — and of those, 25.7% are weak, including wikipedia.org, github.com and apache.org. For a page being cached that is a sensible choice, since a weak tag survives compression and other transformations that change the bytes without changing the meaning. For an API endpoint people update, it removes a feature nobody realises they have lost.

If-Range is the third case and works differently again. The restriction there sits on the client: section 13.1.5 says a client must not generate an If-Range header containing a weak entity tag at all, so resuming a partial download needs a strong validator by construction rather than by comparison.

Honest limits, and how this was checked

This compares two tags you paste. It does not fetch anything, so it cannot tell you what your own server sends — a browser cannot read arbitrary response headers from another origin, and any tool that claims otherwise is proxying the request through a server. Your browser's developer tools will show you the header in one click, which is the right way to get it.

One thing this page deliberately does not claim: that servers commonly emit syntactically invalid ETags. That was the second half of the idea, and measuring killed it. Zero of the 35 real ETags sampled were malformed. Frameworks emit this header; almost nobody writes one by hand. The validator still explains malformed input, because a reader who has typed one deserves an answer, but it is not the interesting fact and the page does not pretend it is.

The comparison logic is checked against the specification's own four-row table, re-extracted from the RFC text on every test run rather than transcribed, so a copying error cannot survive. There are 513 assertions and 14 negative controls. Two of my own test fixtures turned out to encode assumptions rather than the grammar — I had a spaced tag down as valid and a backslashed one as invalid, and the grammar says the opposite on both counts.

Why is it free?

This is string comparison. It runs in your browser, there is no server to pay for, and there is nothing to sign up to.

Nothing you type is uploaded, stored or logged. ETags are opaque by design and sometimes encode more about a resource than their author intended, so it is worth stating that they stay in the tab.