CanonicalTag.com logo, a canonical tag referenceCanonicalTag.comThe canonical tag, explained
URL Variants & Duplicate URLs

Canonical in the HTTP Header

Files without an HTML head can still declare a canonical URL, through a Link response header that Google supports for web search.

VerdictSupported by Google; use it for PDFs and other files

A canonical for files that have no head

A canonical HTTP header is a rel="canonical" annotation sent in the HTTP Link response header rather than written as an HTML <link> element. Google supports it for web search, and it is the right tool for PDFs, Word documents and other non-HTML files, which have no <head> to hold a tag.

Link: <https://www.example.com/downloads/white-paper.pdf>; rel="canonical"

Two standards sit behind that line. RFC 6596, published in April 2012 by M. Ohye and J. Kupke, defines the canonical link relation, and its own example is already in header form. RFC 8288, "Web Linking" (October 2017), defines the Link header field that carries it, replacing RFC 5988. The header and the element express the same relation through different channels: one in the response metadata, one in the document.

The name trips people up in one recurring way. There is no X-Canonical header; anything using that name is invented. The documented form is a Link header whose rel is canonical.

What Google supports, and what is unknown

Google's documentation is direct: "Google supports this method for web search results only" (Google Search Central). It lists two advantages, that the header does not increase page size and can map an unlimited number of duplicates, and one drawback, that the mapping gets hard to maintain on large sites or where URLs change often. Google files the header and the HTML element under the same method, a rel="canonical" annotation it calls a strong signal. Strong is still a hint; Google may pick a different canonical.

Google's worked example concerns format duplicates. A white paper published as both PDF and Word sits at two URLs, and to make the PDF canonical the header goes on the Word document's response, pointing at the PDF. The HTML element, Google notes, only works for HTML pages. The original June 2011 announcement by Pierre Far ran the other direction, with a PDF's header pointing at an HTML page. Either direction fits the method: the header sits on the duplicate and names whichever URL should be canonical.

Three details from the documentation matter in practice:

  • Absolute URLs. Google asks for absolute URLs in the header. RFC 8288 allows relative references, which parsers must resolve, but following Google's request removes any doubt about the host.
  • An outdated reference. Google's page still says the header is "as defined by RFC5988." That RFC was obsoleted by RFC 8288; the syntax used here did not change.
  • Web search only. Other Google surfaces are not covered by the statement, so do not assume the header affects them.

Bing's position is unknown. No Bing documentation or staff statement confirming or denying support was found. One vendor guide says only Google supports the header, others assume Bing does, and Bing's December 2025 duplicate-content post does not mention it. Treat Bing support as unconfirmed.

Syntax rules from RFC 8288

The header's grammar is short, and four of its rules matter for a canonical:

  1. Angle brackets are mandatory. The target URI goes inside < >. Link: https://…; rel="canonical" is not a valid link-value.
  2. One rel per link-value. The RFC says rel "MUST be present but MUST NOT appear more than once in a given link-value," and parsers ignore repeats.
  3. Several links may share a header. Link-values are comma-separated, and multiple Link header lines are also legal, which is how a canonical coexists with other relations.
  4. Quoting is conventional. Because canonical is a plain token, rel=canonical without quotes is syntactically valid; quoting it matches Google's and RFC 6596's examples.
Link: <https://example.org/>; rel="start", <https://example.org/index>; rel="index"

That example from RFC 8288 shows the comma form. A canonical added to a response that already sends other Link values should join the list or sit on its own line, not replace what is there.

Sending the header from Apache, nginx or PHP

Apache

mod_headers allows Header in server config, virtual hosts, directories and .htaccess (with the FileInfo override). Google's docx-to-PDF case looks like this:

<Files "white-paper.docx">
  Header append Link "<https://www.example.com/downloads/white-paper.pdf>; rel=\"canonical\""
</Files>

The verb matters. append joins the value to any existing Link header with a comma. set replaces the whole header, which can silently remove preload or REST API links another module added. Apache warns that add can create duplicate header lines and says "Generally set, append or merge should be used instead." The default condition, onsuccess, skips non-2xx responses; always includes them.

nginx

location = /downloads/white-paper.docx {
    add_header Link '<https://www.example.com/downloads/white-paper.pdf>; rel="canonical"';
}
# self-referencing canonical for every PDF, ignoring query strings:
location ~* \.pdf$ {
    add_header Link '<https://www.example.com$uri>; rel="canonical"';
}

The second block is an adaptation that uses the standard $uri variable, which excludes the query string, so parameterized copies of a PDF all name the clean URL. Two nginx behaviors cause most surprises. add_header applies only to 200, 201, 204, 206, 301, 302, 303, 304, 307 and 308 responses unless always is added. And headers are inherited from the enclosing level only if the current level defines no add_header of its own, so a location that adds a canonical quietly drops server-level headers such as HSTS. nginx 1.29.3 introduced add_header_inherit (on, off or merge) to change that.

PHP

header('Link: <https://www.example.com/downloads/white-paper.pdf>; rel="canonical"', false);

The second argument is the one to get right. PHP's header() replaces an earlier header of the same name by default; passing false adds a second header instead, which keeps WordPress's or a framework's own Link headers intact.

Mistakes specific to header canonicals

  • A header and an HTML canonical that disagree. The usual cause is a CDN rule or plugin adding a header while the template writes a different <link>. Google says not to specify different canonicals for one page through different techniques, and John Mueller wrote in July 2026 that "There's no publicly defined order of precedence for metadata reconciliation here." Any claim that the header wins, or that the HTML wins, has no source. Screaming Frog counts both channels together and reports differing targets as "Multiple Conflicting."
  • A relative target. Valid under the RFC, but Google asks for absolute URLs.
  • No angle brackets. The value is not a valid link-value without them.
  • Overwriting other headers. Apache's Header set Link and nginx's per-location add_header both remove values you may still need.
  • Mistaking other Link headers for canonicals. WordPress has sent Link: <{api_root}>; rel="https://api.w.org/" since 4.4.0, sometimes with a rel="alternate"; type="application/json" entry. Neither is a canonical; parse for rel="canonical" specifically.
  • Pointing at a bad target. RFC 6596 says the target must not return an error such as a 4xx and should not be the source of a permanent redirect. A header naming a redirected or noindexed file sends a signal Google cannot act on cleanly.

Verifying the header

curl -sI https://www.example.com/downloads/white-paper.docx | grep -i '^link:'
# some CDNs and apps answer HEAD differently from GET; this shows GET headers:
curl -s -D - -o /dev/null https://www.example.com/downloads/white-paper.docx | grep -i '^link:'

-I sends a HEAD request, and -D - prints the headers of a normal GET while -o /dev/null discards the body. Run both, because a header that appears on HEAD but not GET (or the reverse) points to a caching or application layer answering differently. Add -L when the URL redirects, so the check reaches the final file. Browser DevTools shows the same data under Network, in Response Headers.

For Google's view, URL Inspection in Search Console accepts PDF URLs and shows the user-declared and Google-selected canonical, which confirms whether the header was read. Screaming Frog reads canonicals from the link element, the HTTP header or both, and flags "Multiple" and "Multiple Conflicting" across the two. Finally, check each response path the file can return. On nginx a header without always will not appear on a 404 or 410, which is usually harmless but confusing when a test URL is wrong.

When the header is the wrong choice

For HTML pages, prefer the <link> element. It is visible in source, every audit tool reads it, and a developer inspecting a template will find it; a header set in a server config is easy to forget. Use a header on HTML only when the markup cannot be changed, and then remove the HTML canonical rather than running both.

Most PDFs need no canonical at all. The header earns its keep when the same document is published at several URLs, or when an HTML version exists that you would rather rank. A PDF that is the only copy of its content can carry a self-referencing header harmlessly, but it gains little from one.

If the aim is to keep a file out of search entirely, a canonical is the wrong instrument. That job belongs to X-Robots-Tag: noindex, which has its own page here.

Frequently asked questions

Can you add a canonical tag to a PDF?

Not inside the file, because a PDF has no HTML head. Instead, the server sends a Link response header with rel="canonical" when the PDF is requested, and Google supports that for web search. Use an absolute URL as the target.

Does Bing support the canonical HTTP header?

It is unconfirmed. No Bing documentation or staff statement either confirming or denying support was found, and vendor guides disagree. Google's support is documented, so the header is safe to use, but do not count on it for Bing without testing.

Is there an X-Canonical header?

No. The canonical is sent in the standard Link header defined by RFC 8288, with rel="canonical" from RFC 6596. A header named X-Canonical is not part of either standard, and none of the Google documentation describes one.

Which wins if the HTTP header and the HTML canonical tag disagree?

There is no published answer. Google says not to declare different canonicals through different methods, and John Mueller wrote in 2026 that there is no publicly defined order of precedence for conflicting metadata. Remove one of them so only a single canonical remains.

Can the canonical HTTP header use a relative URL?

RFC 8288 permits relative references and requires parsers to resolve them, but Google asks for absolute URLs in the header. Following Google avoids the canonical resolving against the wrong host or protocol.

How do I check whether a canonical header is being sent?

Request the file with curl and filter the output for the Link line, once with -I and once as a GET with -D -, since some servers answer HEAD differently. Then inspect the URL in Search Console to confirm Google read the declared canonical.

Top