If-None-Match: asking whether anything changed
If-None-Match sends back the ETag a client already holds. If it still matches, the server answers 304 Not Modified with no body, and the client reuses its stored copy.
At a glance
- Direction
- Request only. It carries entity tags the client already has.
- Defined in
- RFC 9110
- When absent
- The server has to send the whole body even when the client already has an identical copy.
- Result on match
- 304 Not Modified for GET and HEAD, 412 Precondition Failed for other methods
- Comparison
- Weak, so W/ prefixed tags can still match
- Takes precedence over
- If-Modified-Since, which is ignored when this header is present
- Multiple tags
- A comma separated list is allowed; a match against any one of them is a match.
In detail
The client is saying it already has one of these versions and only wants the body if the current version is not among them. When the server finds a match it stops, sends 304 with the validators and any updated cache headers, and sends no body at all. The saving is the payload, and on a large document or a slow connection it is the whole cost of the request.
Comparison is weak here, which means a tag marked with the W/ prefix can still match. That is the right rule for caching: two representations that differ only in a timestamp comment are equivalent for the purpose of reusing a stored copy, even though they are not byte identical.
It also has a write side. Sending If-None-Match: * on a PUT means create this only if nothing exists at this URL, and the server answers 412 Precondition Failed if something does. That gives you an atomic create without a separate existence check and without the race between the check and the write.
When a client sends both this header and If-Modified-Since, the server must ignore the date entirely. Entity tags are more precise than second resolution timestamps, so a request carrying both is answered on the tag alone, and a mismatch there produces a full response even if the date suggests nothing changed.
Examples
GET /api/report HTTP/1.1
If-None-Match: "9c2f7a1e4b"
HTTP/1.1 304 Not Modified
ETag: "9c2f7a1e4b"
Cache-Control: max-age=60PUT /documents/draft-7 HTTP/1.1
If-None-Match: *
HTTP/1.1 412 Precondition FailedThings that catch people out
- The tag must be sent back exactly as received, quotation marks and W/ prefix included. Stripping the quotes produces a mismatch and a full response every time.
- A 304 must not have a body. Frameworks that serialise a response object before checking the precondition often send one anyway, and some clients then hang waiting for a length that will never arrive.
- A load balanced fleet that generates different tags per machine turns every conditional request into a full download, because the tag from one server never matches another.
Try it: HTTP Headers Checker
Check a live URL or paste headers you already have. It grades six security headers from A+ to F and lists every other header the response returned.
HTTP Headers Checker
LOCAL · Browser-OnlyView HTTP response headers for any URL
Enter any website URL to fetch and analyze its HTTP response headers. We'll automatically add https:// if needed.
Why Check Security Headers?
Security headers protect your website against common attacks like XSS, clickjacking, and MIME sniffing. They're set by your web server and cost nothing to implement. Missing security headers are one of the most common findings in security audits.
Related HTTP headers
All http headers →ETag: version identifiers for conditional requests
How an ETag is compared, when to use a weak tag, how it drives 304 responses and 412 conflicts, and why compression changes the tag a server sends.
If-Modified-Since: date based conditional requests
How If-Modified-Since produces a 304, why it only applies to GET and HEAD, when servers must ignore it, and why entity tags are preferred where both exist.
If-Match: safe updates and the lost update problem
How If-Match turns a PUT or PATCH into a conditional write, why it uses strong comparison, and how 412 Precondition Failed prevents silent overwrites.
Cache-Control: directives for browsers and shared caches
Every Cache-Control directive that matters, the difference between no-cache and no-store, and how to cache immutable assets forever without breaking deploys.
If-Unmodified-Since: a date based conditional write
How If-Unmodified-Since guards a write with a timestamp instead of an entity tag, when servers ignore it, and why an ETag is the stronger guarantee.
Pragma: a deprecated header still copied everywhere
What Pragma: no-cache ever did, why it only applied to requests, why it is deprecated in RFC 9111, and whether there is any reason to keep sending it.
Tools for this
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body