Currently Available: Need a skilled Software Developer for your next project?
Categories
APIs

How to Use ETags for Conditional HTTP Requests

When a client requests a resource from an HTTP server, the server can return an ETag, a header whose value identifies a particular version of the response. The client can send that value with a later request, and the server checks whether the resource has changed. If it has not, the server avoids sending the same response body again.

Use ETags to validate cached responses or to prevent a client from overwriting a resource that changed since it was read. The right request header depends on the goal: If-None-Match checks whether a cached response is still current, while If-Match checks whether a write is based on the current version.

Validate a cached response with If-None-Match

After receiving a response with an ETag, a client can store both the response body and its ETag. On a later GET or HEAD request, it sends that ETag in the If-None-Match request header. The server compares the supplied ETag with the ETag for the current resource version.

If the ETags match, the server returns 304 Not Modified without a response body, and the client reuses its stored body. If they do not match, the server returns the current response, typically with 200 OK and a new ETag. This conditional request saves response bandwidth, though it still requires a network round trip and the server must perform enough work to evaluate the condition. The HTTP caching overview describes this revalidation pattern.

For example, a client that previously received an ETag for a product record sends that same value in If-None-Match when it requests the record again. The client should store the ETag as an opaque value and return it unchanged, without interpreting its contents.

Caching directives determine whether a client stores and revalidates the response. Cache-Control: no-cache allows storage but requires validation before reuse. Cache-Control: no-store tells caches not to store the response, so ETag revalidation does not apply to that stored response.

Prevent stale writes with If-Match

A client can use If-Match when it wants to update or delete a resource only if the server still has the version the client previously read. The client sends the ETag it received with that earlier response. The server performs the write only when the current ETag matches; if the resource has changed, the server rejects the request with 412 Precondition Failed.

This check prevents a stale client from silently overwriting a newer update. After a successful change, the server should return the ETag for the updated representation so the client can use it in a later conditional request.

Use If-Match for version-sensitive writes, such as editing a record that another client might update at the same time. The ETag must represent the resource version the server is protecting, and the server must check it as part of handling the write.

Choose strong or weak ETags

A strong ETag identifies a representation (the response data sent to the client) by its exact bytes. A weak ETag, marked with the W/ prefix, identifies a representation the server considers semantically equivalent even if its bytes differ. For example, a server might treat two representations as equivalent when formatting changes but the underlying information remains the same. The ETag caching explanation covers this distinction.

Weak ETags suit cache validation when byte-for-byte identity is unnecessary. Strong ETags are required when a client needs to combine separately downloaded byte ranges safely. A range request asks the server for part of a representation. The client can send If-Range with a strong ETag to check whether that representation still matches. If the validator still matches, the server returns 206 Partial Content; if it does not, the server returns the complete representation with 200 OK. The MDN reference for If-Range describes this behavior.

Do not use a weak ETag to confirm that separate byte ranges belong to the exact same representation. Semantic equivalence does not guarantee that their bytes can be assembled correctly.

Check caching and browser access

An ETag saves bandwidth when a matching cached response lets the server return 304 Not Modified. It does not automatically reduce server processing: the server still needs to determine whether the resource has changed. If generating a response requires expensive work, calculate or retrieve the resource version efficiently rather than rebuilding the full response solely to compare ETags. The documented limitations of ETags include this server-side cost.

For browser requests to a different origin (a different scheme, host, or port), the browser does not expose the ETag response header to client-side code by default. The server must include Access-Control-Expose-Headers: ETag in its Cross-Origin Resource Sharing (CORS) response so the browser lets that code read the value.

If multiple servers handle requests for the same resource, make sure they produce ETags that agree for the same representation. Otherwise, one server might reject an ETag issued by another or force the client to download an unchanged response again. The server should also account for response headers that can change even when the body does not. After a 304, the client reuses its cached content and metadata. The server’s ETag design must let the client reuse the content and headers it needs.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *