Set Vary to the request header names your server uses to select a public page’s representation. On a Mac, test one header at a time, compare the returned document and metadata, and check the default response before changing the configuration.

This guide is for someone maintaining a public document and checking its delivery from Mac Terminal. The worked example is a synthetic “Shape Guide” available as HTML or plain text at one URL. The task is to identify its actual selection inputs, configure the corresponding response header, and verify the result.

What belongs in a page’s Vary header?

Vary names request fields that might influence representation selection, beyond the request method and target URL. Its values are header names, such as Accept, rather than the requested media types. It describes selection behavior; adding it does not implement that behavior. RFC 9110: HTTP Semantics, section 12.5.5.

For example, if the server selects HTML or plain text using Accept, the relevant response field is Vary: Accept. If a delivery layer also selects compressed or uncompressed output using Accept-Encoding, preserve that dimension too: Vary: Accept, Accept-Encoding. These are conditional examples, not a universal configuration for every page. Content negotiation.

The practical question is: could a cached response selected for one request be unsuitable for another because this header changed? HTTP caching requires the nominated fields to match before reuse without revalidation. An absent nominated field matches another absent field, not a present one. RFC 9111: HTTP Caching, section 4.1.

Start by writing a selection inventory. Check the application’s document-selection rules and any response transformations applied afterward. A changed result is useful evidence, but an unchanged result from two requests does not establish that a header is irrelevant across every supported value.

Build a request matrix before editing anything

For the synthetic Shape Guide, suppose the intended behavior is HTML for an HTML preference, plain text for a plain-text preference, and HTML when Accept is absent. Both versions contain the same neutral information: “Circle, square, triangle.” These are illustrative requirements, not observations from a published site.

Test Request setting Intended result What to inspect
HTML Accept: text/html HTML document Body, Content-Type, Vary
Plain text Accept: text/plain Plain-text document Body, Content-Type, Vary
Default No Accept field HTML document Default selection and Vary
Repeat HTML after plain text HTML document again Whether the earlier variant affects delivery
Unused input Change a header absent from selection rules Same selected representation Whether that header needs investigation

Keep compression fixed during the first comparison. Otherwise, a byte difference could reflect compression rather than a different document. Investigate format selection first, then compression separately. The distinction follows the separate roles of Accept and Accept-Encoding. Content negotiation.

Record meaningful differences rather than relying only on file size. For this example, the plain-text response should contain the shape names without HTML markup, and its media type should describe plain text. A changing generated timestamp would require investigation before treating every byte difference as a new variant.

This matrix is a diagnostic aid, not a complete negotiation test suite. Once the basic cases work, add the actual mixed preferences and quality values your page supports. A simple single-type request cannot exercise every branch of a selection algorithm.

Capture comparable responses in Mac Terminal

You need a public test document containing synthetic material, its final HTTPS URL, and a Mac with bash and curl available. The example assumes the test document already supports the HTML/plain-text behavior described above. It does not create, upload, or publish that document.

Open Terminal and paste the complete block below. Enter your synthetic document’s URL when prompted. The script creates a new temporary report directory and keeps each response body beside its headers; it does not overwrite an earlier report.

bash <<'BASH'
set -eu

printf 'Public synthetic page URL: ' > /dev/tty
IFS= read -r page_url < /dev/tty

case "$page_url" in
  https://*) ;;
  *) printf 'Enter an HTTPS URL.\n' >&2; exit 1 ;;
esac

report_dir=$(mktemp -d "${TMPDIR:-/tmp}/vary-check.XXXXXX")
printf 'Report directory: %s\n' "$report_dir"

for sample in html plain absent html-again; do
  case "$sample" in
    html|html-again) accept_header='Accept: text/html' ;;
    plain) accept_header='Accept: text/plain' ;;
    absent) accept_header='Accept:' ;;
  esac

  curl --disable --silent --show-error --fail \
    --connect-timeout 5 --max-time 20 \
    --header "$accept_header" \
    --header 'Accept-Encoding: identity' \
    --dump-header "$report_dir/$sample.headers" \
    --output "$report_dir/$sample.body" \
    --url "$page_url"
done

printf 'Finished. Responses saved in: %s\n' "$report_dir"
BASH

Here, --header supplies the controlled request field, and Accept: removes curl’s internally generated Accept field. --dump-header and --output save headers and bodies separately. The connection and transfer time limits bound each request. These options are documented in the curl manual.

The script stops when curl reports a transfer failure or an HTTP error covered by --fail. Inspect the reported directory before retrying: earlier captures can remain, and a failed transfer can leave incomplete files. It intentionally does not follow redirects, so check the status line in every header file. If you captured a redirect, use the final document URL and start a new report. curl manual.

Open the report directory in Finder using the path printed by the script. Inspect the files in a plain-text editor. Compare html.body with plain.body, then compare html.body with html-again.body. Inspect absent.headers as carefully as the explicit-preference responses.

Treat the saved results as observations from this request sequence. They do not prove that a shared cache stored anything. If you need to exercise cache reuse, repeat the sequence through the intended delivery path under its documented cacheable conditions, and also reverse the order so plain text comes first.

Apply the result at the response-producing layer

For the illustrative Shape Guide, the format-selection evidence should support Accept as a selecting field. Configure it where the HTTP response is generated or finalized. If another layer already contributes a necessary Vary member, preserve it when adding the format-selection member. The finished list should describe the combined selection behavior. RFC 9110: HTTP Semantics.

The following is a response-header fragment for the example when both format selection and compression negotiation are active. It is not a complete HTTP response or a server configuration file.

Vary: Accept, Accept-Encoding

Use the same intended Vary list on the negotiated variants and the default response, and preserve it on applicable 304 Not Modified responses. MDN explicitly documents this consistency requirement. Make these response paths part of your verification rather than checking only the first successful HTML response. Vary header.

Adding a meta element with http-equiv="Vary" is not a supported substitute. WHATWG defines a specific set of HTML pragma directives, which does not include Vary, and explains that those directives are largely separate from HTTP headers. Use actual response-header configuration. HTML Standard: Pragma directives.

If your publishing interface cannot set response headers, check whether the hosting or application layer offers documented support. When that is unavailable, a practical alternative for this synthetic example is to give the HTML and plain-text documents separate URLs with stable representations, rather than negotiating their formats at one URL. This removes that particular selection dimension; other transformations still need their own assessment.

Diagnose missing, excessive, and misleading variation

Use the captures to choose the next investigation. The following decision aid applies to the example’s stated behavior; it is not a claim about any particular hosting service.

Observation Next investigation
HTML and plain-text requests produce different formats, but Vary omits Accept Inspect where the final response header is assembled
Explicit variants include Accept, but the default response omits it Inspect the fallback response path
The repeated HTML request receives the plain-text version Compare selection at the origin with delivery through the cache
Every request produces the same HTML document Check whether format negotiation exists before adding a format-related member
An unrelated header appears in Vary Find the selection rule that requires it before removing it
A browser resize changes layout without changing delivered HTML Check whether this is responsive presentation rather than server selection

The missing-default case deserves particular attention: RFC 9111 describes how omitting Vary from a default response can cause that response to be selected for later requests despite available alternatives. Correct the default path alongside the explicit variants. RFC 9111: HTTP Caching.

Avoid using Vary: * as a shortcut for an unfinished inventory. Under HTTP caching rules, a stored response containing that member always fails the matching test. It does not identify which request fields select your document. RFC 9111: HTTP Caching.

A browser check remains useful after the Terminal comparison. WHATWG’s Fetch Standard explicitly takes Vary into account when selecting an HTTP-cache response. Check the document through its normal browser loading path as well as through controlled curl requests. Fetch Standard: HTTP-network-or-cache fetch.

Keep page delivery and Google Search requirements aligned

For device-dependent pages, distinguish responsive design from dynamic serving. Google documents responsive design as serving the same HTML at the same URL across devices, while dynamic serving selects different HTML using User-Agent and relies on Vary: User-Agent. Google recommends responsive design for ease of implementation and maintenance. Mobile site and mobile-first indexing best practices.

Consequently, a synthetic Shape Guide that merely rearranges the same HTML with CSS does not gain a reason to vary on User-Agent from that layout change alone. If the server actually selects different HTML by device, add those device cases to the request matrix. Google also advises keeping the primary content equivalent between desktop and mobile versions. Mobile site and mobile-first indexing best practices.

Finish with a small, reviewable delivery record: the document-selection rules, the request matrix, the captured responses, and the resulting Vary list. Each listed header should have an identifiable role, each supported variant should remain distinguishable, and the default response should follow the same delivery contract.

Sources